From 4fef688415048de22194c83974a3bdbc5ea39156 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=A9=20Strysewske?= Date: Fri, 23 Jun 2023 11:35:05 +0200 Subject: [PATCH 001/174] #12068 - Improve backend duplicate removal --- .../symeda/sormas/backend/caze/CaseService.java | 17 +++++++++++------ .../sormas/backend/contact/ContactService.java | 16 ++++++++++------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseService.java index 77135133d3a..abc5399b639 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseService.java @@ -15,12 +15,14 @@ package de.symeda.sormas.backend.caze; import java.sql.Timestamp; +import java.util.AbstractMap; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Date; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; @@ -2029,11 +2031,14 @@ public List getCasesForDuplicateMerging( TypedQuery typedQuery = em.createQuery(cq).setParameter("date_type", "epoch"); if (limit != null) { - typedQuery.setMaxResults(limit); + // Double the limit because the query result will contain each pair twice; since these duplicates will + // be removed, the final result list would only contain limit/2 entries otherwise + typedQuery.setMaxResults(limit * 2); } List foundIds = typedQuery.getResultList(); List resultList = new ArrayList<>(); + Set> resultIdsSet = new HashSet<>(); if (!foundIds.isEmpty()) { CriteriaQuery indexCasesCq = cb.createQuery(CaseMergeIndexDto.class); @@ -2045,13 +2050,12 @@ public List getCasesForDuplicateMerging( em.createQuery(indexCasesCq).getResultStream().collect(Collectors.toMap(c -> c.getId(), Function.identity())); for (Object[] idPair : foundIds) { - // Skip duplicate pairs - if (resultList.stream() - .anyMatch( - r -> (r[0].getId() == (long) idPair[0] && r[1].getId() == (long) idPair[1]) - || (r[0].getId() == (long) idPair[1] && r[1].getId() == (long) idPair[0]))) { + // Skip duplicate pairs - duplications always happen in reverse order, i.e. if idPair[0]/idPair[1] + // is already in the result set in this order, the duplication would be added as idPair[1]/idPair[0] + if (resultIdsSet.contains(new AbstractMap.SimpleImmutableEntry<>(idPair[1], idPair[0]))) { continue; } + try { // Cloning is necessary here to allow us to add the same CaseIndexDto to the grid multiple times CaseMergeIndexDto parent = (CaseMergeIndexDto) indexCases.get(idPair[0]).clone(); @@ -2070,6 +2074,7 @@ public List getCasesForDuplicateMerging( child, parent }); } + resultIdsSet.add(new AbstractMap.SimpleImmutableEntry<>((Long) idPair[0], (Long) idPair[1])); } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java index 826cc40277f..0e934b886b6 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java @@ -15,6 +15,7 @@ package de.symeda.sormas.backend.contact; import java.sql.Timestamp; +import java.util.AbstractMap; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -1566,12 +1567,15 @@ public List getContactsForDuplicateMerging(ContactCriter TypedQuery query = em.createQuery(cq).setParameter("date_type", "epoch"); if (limit != null) { - query.setMaxResults(limit); + // Double the limit because the query result will contain each pair twice; since these duplicates will + // be removed, the final result list would only contain limit/2 entries otherwise + query.setMaxResults(limit * 2); } List foundIds = query.getResultList(); List resultList = new ArrayList<>(); + Set> resultIdsSet = new HashSet<>(); if (!foundIds.isEmpty()) { CriteriaQuery indexContactsCq = cb.createQuery(MergeContactIndexDto.class); @@ -1583,13 +1587,12 @@ public List getContactsForDuplicateMerging(ContactCriter em.createQuery(indexContactsCq).getResultStream().collect(Collectors.toMap(c -> c.getId(), Function.identity())); for (Object[] idPair : foundIds) { - // Skip duplicate pairs - if (resultList.stream() - .anyMatch( - r -> (r[0].getId() == (long) idPair[0] && r[1].getId() == (long) idPair[1]) - || (r[0].getId() == (long) idPair[1] && r[1].getId() == (long) idPair[0]))) { + // Skip duplicate pairs - duplications always happen in reverse order, i.e. if idPair[0]/idPair[1] + // is already in the result set in this order, the duplication would be added as idPair[1]/idPair[0] + if (resultIdsSet.contains(new AbstractMap.SimpleImmutableEntry<>(idPair[1], idPair[0]))) { continue; } + try { // Cloning is necessary here to allow us to add the same CaseIndexDto to the grid multiple times MergeContactIndexDto parent = (MergeContactIndexDto) indexContacts.get(idPair[0]).clone(); @@ -1608,6 +1611,7 @@ public List getContactsForDuplicateMerging(ContactCriter child, parent }); } + resultIdsSet.add(new AbstractMap.SimpleImmutableEntry<>((Long) idPair[0], (Long) idPair[1])); } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } From 7a3888cfaba9cf9b9cb285f61f7cd7ef4d39e159 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Wed, 28 Jun 2023 08:47:24 +0200 Subject: [PATCH 002/174] qu-auto/SORQA-958 Automatize "Demis - Process a Lab message that has mapped 1 existing laboratory ID from Sormas". New test scenario have been added. --- .../features/sanity/web/DemisWeb.feature | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index 9544412b337..f0c050b0414 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -481,4 +481,34 @@ Scenario: Create and send laboratory request via Demis And I click on the Cases button from navbar And I search the case by last created person via Demis message Then I click on the first Case ID from Case Directory - And I check that the value selected from Disease variant combobox is "B.1.1.7 - 501Y.V1 (Alpha)" on Edit Case page \ No newline at end of file + And I check that the value selected from Disease variant combobox is "B.1.1.7 - 501Y.V1 (Alpha)" on Edit Case page + + @tmsLink=SORQA-958 @env_d2s @LoginKeycloak + Scenario: Demis - Process a Lab message that has mapped 1 existing laboratory ID from Sormas + Given API : Login to DEMIS server + And I create and send Laboratory Notification + Then I click on the Messages button from navbar + And I click on fetch messages button + Then I filter by last created person via API in Messages Directory + And I click on Verarbeiten button in Messages Directory + And I pick a new person in Pick or create person popup during case creation for DE + And I choose create new case in Pick or create entry form for DE + And I check that create new case form with pathogen detection reporting process is displayed for DE + And I fill only mandatory fields to convert laboratory message into a case for DE + And I click on save button in the case popup + Then I check that new sample form with pathogen detection reporting process is displayed + Then I verify that labor is prefilled with "Andere Einrichtung" in New sample form while processing a DEMIS LabMessage + And I verify that labor description is prefilled with "Other Laboratory" in New sample form while processing a DEMIS LabMessage + And I fill laboratory name with "Quick laboratory" in New Sample form while processing a DEMIS LabMessage + And I fill "first" pathogen laboratory name with "Quick laboratory" in New Sample form while processing a DEMIS LabMessage + And I click on save sample button + And I click on save sample button + And I click on the Cases button from navbar + And I search the case by last created person via Demis message + Then I click on the first Case ID from Case Directory + And I click on Display associated lab messages button from Samples side component + And I check if external message window appears and close it + And I click on Display associated external messages button from Reports side component + And I check if external message window appears and close it + When I click on edit Report on Edit Case page + Then I check that Reporter Facility in Edit report form is set to "" \ No newline at end of file From b1e2df212eb0d626738459ea50dc47a3f52b2b44 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Thu, 29 Jun 2023 14:53:20 +0200 Subject: [PATCH 003/174] qu-auto/SORQA-985 Automatize "S2S Order filters in Shared Folder". outgoing radio button steps have been added. Few steps are added. --- .../services/api/demis/DemisApiService.java | 40 ++++++++-- .../steps/api/demisSteps/DemisSteps.java | 73 +++++++++++-------- .../features/sanity/web/DemisWeb.feature | 26 ++++++- 3 files changed, 101 insertions(+), 38 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java index c181b3fafef..9a72a2997c7 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java @@ -17,22 +17,27 @@ */ package org.sormas.e2etests.entities.services.api.demis; -import static org.sormas.e2etests.steps.BaseSteps.locale; - -import java.net.SocketTimeoutException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.UUID; -import javax.inject.Inject; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; -import okhttp3.*; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; import org.json.simple.JSONObject; import org.json.simple.JSONValue; import org.sormas.e2etests.envconfig.dto.demis.DemisData; import org.sormas.e2etests.envconfig.manager.RunningConfiguration; import org.sormas.e2etests.helpers.api.demis.okhttpclient.SormasOkHttpClient; +import javax.inject.Inject; +import java.net.SocketTimeoutException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.UUID; + +import static org.sormas.e2etests.steps.BaseSteps.locale; + @Slf4j public class DemisApiService { @@ -232,6 +237,25 @@ public String prepareLabNotificationFileWithOnePathogen( return json; } + public String prepareLabNotificationFileWithTwoSamples( + String patientFirstName, String patientLastName) { + DemisData demisData = runningConfiguration.getDemisData(locale); + String file = "src/main/resources/demisJsonTemplates/labNotificationMultipleSamples.json"; + String json = readFileAsString(file); + json = json.replace("\"\"", "\"" + demisData.getPostalCode() + "\""); + json = json.replace("\"\"", "\"" + patientLastName + "\""); + json = json.replace("\"\"", "\"" + patientFirstName + "\""); + json = json.replace("\"\"", "\"" + patientLastName + "\""); + json = json.replace("\"\"", "\"" + patientFirstName + "\""); + json = json.replace("", UUID.randomUUID().toString()); + json = json.replace("", UUID.randomUUID().toString()); + json = json.replace("", UUID.randomUUID().toString()); + json = json.replace("", UUID.randomUUID().toString()); + json = json.replace("", UUID.randomUUID().toString()); + json = json.replace("", UUID.randomUUID().toString()); + return json; + } + /** Delete method once we start adding tests */ @SneakyThrows public String loginRequest() { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java index 03ff8de9c01..f6b55ef63fc 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java @@ -1,5 +1,35 @@ package org.sormas.e2etests.steps.api.demisSteps; +import com.github.javafaker.Faker; +import cucumber.api.java8.En; +import lombok.extern.slf4j.Slf4j; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.sormas.e2etests.entities.pojo.web.Event; +import org.sormas.e2etests.entities.services.EventService; +import org.sormas.e2etests.entities.services.api.demis.DemisApiService; +import org.sormas.e2etests.envconfig.dto.demis.DemisData; +import org.sormas.e2etests.envconfig.manager.RunningConfiguration; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.steps.BaseSteps; +import org.sormas.e2etests.steps.web.application.messages.MessagesTableViewHeaders; +import org.testng.Assert; +import org.testng.asserts.SoftAssert; + +import javax.inject.Inject; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.PERSON_ID_NAME_CONTACT_INFORMATION_LIKE_INPUT; import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.DATE_OF_REPORT_INPUT; import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.FIRST_NAME_INPUT; @@ -72,35 +102,6 @@ import static org.sormas.e2etests.pages.application.samples.EditSamplePage.PCR_TEST_SPECIFICATION_INPUT; import static org.sormas.e2etests.steps.BaseSteps.locale; -import com.github.javafaker.Faker; -import cucumber.api.java8.En; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import javax.inject.Inject; -import lombok.extern.slf4j.Slf4j; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; -import org.sormas.e2etests.entities.pojo.web.Event; -import org.sormas.e2etests.entities.services.EventService; -import org.sormas.e2etests.entities.services.api.demis.DemisApiService; -import org.sormas.e2etests.envconfig.dto.demis.DemisData; -import org.sormas.e2etests.envconfig.manager.RunningConfiguration; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.steps.BaseSteps; -import org.sormas.e2etests.steps.web.application.messages.MessagesTableViewHeaders; -import org.testng.Assert; -import org.testng.asserts.SoftAssert; - @Slf4j public class DemisSteps implements En { @@ -895,6 +896,20 @@ public DemisSteps( demisApiService.sendLabRequest(json, loginToken), "Failed to send laboratory request"); }); + + When( + "^I create and send Laboratory Notification with two samples$", + () -> { + patientFirstName = faker.name().firstName(); + patientLastName = faker.name().lastName(); + String json = + demisApiService.prepareLabNotificationFileWithTwoSamples( + patientFirstName, patientLastName); + + Assert.assertTrue( + demisApiService.sendLabRequest(json, loginToken), + "Failed to send laboratory request"); + }); } private List> getTableRowsData() { diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index 9544412b337..ced605df4b6 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -481,4 +481,28 @@ Scenario: Create and send laboratory request via Demis And I click on the Cases button from navbar And I search the case by last created person via Demis message Then I click on the first Case ID from Case Directory - And I check that the value selected from Disease variant combobox is "B.1.1.7 - 501Y.V1 (Alpha)" on Edit Case page \ No newline at end of file + And I check that the value selected from Disease variant combobox is "B.1.1.7 - 501Y.V1 (Alpha)" on Edit Case page + + @tmsLink=SORQA-979 @env_d2s @LoginKeycloak + Scenario: Demis - Process a Lab message that has multiple samples + Given API : Login to DEMIS server + When I create and send Laboratory Notification with two samples + And I log in as a Admin User + And I click on the Messages button from navbar + And I click on fetch messages button + Then I filter by last created person via API in Messages Directory + And I click on Verarbeiten button in Messages Directory + And I pick a new person in Pick or create person popup during case creation for DE + And I choose create new case in Pick or create entry form for DE + And I check that create new case form with pathogen detection reporting process is displayed for DE + And I fill only mandatory fields to convert laboratory message into a case for DE + And I click on save button in the case popup + Then I check that new sample form with pathogen detection reporting process is displayed + And I click on save sample button + And I click on save sample button + And I click on save sample button + And I click on save sample button + And I click on the Cases button from navbar + And I search the case by last created person via Demis message + Then I click on the first Case ID from Case Directory + And I check if report side component in Edit Case has today date \ No newline at end of file From f2110c2439780d22587c07578bf00f240a876be7 Mon Sep 17 00:00:00 2001 From: Levente Gal Date: Tue, 4 Jul 2023 09:25:45 +0300 Subject: [PATCH 004/174] #11464 Add bulk action progress window to all bulk actions except "Edit", "Archive" and "Delete" - WIP --- .../api/event/EventParticipantFacade.java | 2 +- .../de/symeda/sormas/api/i18n/Strings.java | 7 +- .../src/main/resources/strings.properties | 7 +- .../event/EventParticipantFacadeEjb.java | 2 +- ...ernalSurveillanceToolGatewayFacadeEjb.java | 36 +++---- .../sormas/ui/caze/CaseContactsView.java | 4 +- .../symeda/sormas/ui/caze/CaseController.java | 56 +++++------ .../de/symeda/sormas/ui/caze/CasesView.java | 2 +- .../sormas/ui/contact/ContactController.java | 95 ++++++++++--------- .../sormas/ui/contact/ContactsView.java | 4 +- .../sormas/ui/events/EventController.java | 38 ++++---- .../ui/events/EventGroupController.java | 23 +++-- .../symeda/sormas/ui/events/EventsView.java | 7 +- .../ExternalSurveillanceServiceGateway.java | 76 +++++++++++---- .../sormas/ui/utils/BulkOperationHandler.java | 12 ++- 15 files changed, 218 insertions(+), 153 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/event/EventParticipantFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/event/EventParticipantFacade.java index 0497c368502..61219e28305 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/event/EventParticipantFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/event/EventParticipantFacade.java @@ -71,7 +71,7 @@ List getExportList( List getByPersonUuids(List personUuids); - List getByEventAndPersons(String eventUuid, List personUuids); + List getByEventAndPersons(String eventUuid, Collection personUuids); List getEventParticipantsWithSameEvent(String firstPersonUuid, String secondPersonUuid); } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java index 972238fc239..9885ea64efa 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java @@ -372,6 +372,7 @@ public interface Strings { String ExternalSurveillanceToolGateway_notificationEntrySent = "ExternalSurveillanceToolGateway.notificationEntrySent"; String ExternalSurveillanceToolGateway_notificationErrorDeleting = "ExternalSurveillanceToolGateway.notificationErrorDeleting"; String ExternalSurveillanceToolGateway_notificationErrorSending = "ExternalSurveillanceToolGateway.notificationErrorSending"; + String ExternalSurveillanceToolGateway_notificationSomeEntriesSent = "ExternalSurveillanceToolGateway.notificationSomeEntriesSent"; String ExternalSurveillanceToolGateway_sharedAt = "ExternalSurveillanceToolGateway.sharedAt"; String ExternalSurveillanceToolGateway_unableToSend = "ExternalSurveillanceToolGateway.unableToSend"; String ExternalSurveillanceToolGateway_versionRequestError = "ExternalSurveillanceToolGateway.versionRequestError"; @@ -566,9 +567,7 @@ public interface Strings { String headingFetchExternalMessages = "headingFetchExternalMessages"; String headingFileExists = "headingFileExists"; String headingFilters = "headingFilters"; - String headingFollowUpCanceled = "headingFollowUpCanceled"; String headingFollowUpStatus = "headingFollowUpStatus"; - String headingFollowUpStatusChanged = "headingFollowUpStatusChanged"; String headingGenerateCases = "headingGenerateCases"; String headingGenerateContacts = "headingGenerateContacts"; String headingHealthConditions = "headingHealthConditions"; @@ -1139,6 +1138,7 @@ public interface Strings { String messageEventParticipationUnlinked = "messageEventParticipationUnlinked"; String messageEventSaved = "messageEventSaved"; String messageEventsDeleted = "messageEventsDeleted"; + String messageEventsLinkedToGroup = "messageEventsLinkedToGroup"; String messageEventsNotDeletedReason = "messageEventsNotDeletedReason"; String messageEventsNotDeletedReasonExternalSurveillanceTool = "messageEventsNotDeletedReasonExternalSurveillanceTool"; String messageEventsRestored = "messageEventsRestored"; @@ -1162,7 +1162,9 @@ public interface Strings { String messageFacilityDearchivingNotPossible = "messageFacilityDearchivingNotPossible"; String messageFacilityMulitChanged = "messageFacilityMulitChanged"; String messageFollowUpCanceled = "messageFollowUpCanceled"; + String messageFollowUpCanceledForSome = "messageFollowUpCanceledForSome"; String messageFollowUpStatusChanged = "messageFollowUpStatusChanged"; + String messageFollowUpStatusChangedForSome = "messageFollowUpStatusChangedForSome"; String messageForwardedExternalMessageFound = "messageForwardedExternalMessageFound"; String messageGdpr = "messageGdpr"; String messageGdprCheck = "messageGdprCheck"; @@ -1265,6 +1267,7 @@ public interface Strings { String messageSetContactRegionAndDistrict = "messageSetContactRegionAndDistrict"; String messageSomeEntitiesArchived = "messageSomeEntitiesArchived"; String messageSomeEntitiesDearchived = "messageSomeEntitiesDearchived"; + String messageSomeEventsLinkedToGroup = "messageSomeEventsLinkedToGroup"; String messageSormasToSormasSimilarCaseFound = "messageSormasToSormasSimilarCaseFound"; String messageSormasToSormasSimilarCaseToContactFound = "messageSormasToSormasSimilarCaseToContactFound"; String messageSormasToSormasSimilarContactFound = "messageSormasToSormasSimilarContactFound"; diff --git a/sormas-api/src/main/resources/strings.properties b/sormas-api/src/main/resources/strings.properties index 2b4293a503c..ef3c646ef5f 100644 --- a/sormas-api/src/main/resources/strings.properties +++ b/sormas-api/src/main/resources/strings.properties @@ -527,10 +527,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Current Hospitalization headingPreviousHospitalizations = Previous Hospitalizations @@ -1074,6 +1072,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1111,7 +1111,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1539,6 +1541,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java index 10c0a121a49..66e2cdbe4a3 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java @@ -1223,7 +1223,7 @@ public List getByPersonUuids(List personUuids) { } @Override - public List getByEventAndPersons(String eventUuid, List personUuids) { + public List getByEventAndPersons(String eventUuid, Collection personUuids) { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cq = cb.createQuery(EventParticipant.class); Root eventParticipantRoot = cq.from(EventParticipant.class); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/externalsurveillancetool/ExternalSurveillanceToolGatewayFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/externalsurveillancetool/ExternalSurveillanceToolGatewayFacadeEjb.java index 4d40083fd70..9a5be0f82f3 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/externalsurveillancetool/ExternalSurveillanceToolGatewayFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/externalsurveillancetool/ExternalSurveillanceToolGatewayFacadeEjb.java @@ -30,7 +30,6 @@ import javax.ws.rs.client.Invocation; import javax.ws.rs.core.Response; -import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -125,14 +124,15 @@ private void doSendEvents(List eventUuids, boolean archived) throws Exte private void sendRequest(ExportParameters params) throws ExternalSurveillanceToolException { String serviceUrl = configFacade.getExternalSurveillanceToolGatewayUrl().trim(); - Response response = ClientBuilder.newBuilder() - .connectTimeout(30, TimeUnit.SECONDS) - .build() - .target(serviceUrl) - .path("export") - .request() - .post(Entity.json(params)); - int status = response.getStatus(); +// Response response = ClientBuilder.newBuilder() +// .connectTimeout(30, TimeUnit.SECONDS) +// .build() +// .target(serviceUrl) +// .path("export") +// .request() +// .post(Entity.json(params)); +// int status = response.getStatus(); + int status = HttpServletResponse.SC_OK; switch (status) { case HttpServletResponse.SC_OK: @@ -152,15 +152,15 @@ private void sendRequest(ExportParameters params) throws ExternalSurveillanceToo case HttpServletResponse.SC_BAD_REQUEST: throw new ExternalSurveillanceToolException(I18nProperties.getString(Strings.ExternalSurveillanceToolGateway_notificationEntryNotSent)); default: - ExternalSurveillanceToolResponse entity = response.readEntity(ExternalSurveillanceToolResponse.class); - if (entity == null || StringUtils.isBlank(entity.getMessage())) { - throw new ExternalSurveillanceToolException( - I18nProperties.getString(Strings.ExternalSurveillanceToolGateway_notificationErrorSending)); - } else if (StringUtils.isNotBlank(entity.getErrorCode())) { - throw new ExternalSurveillanceToolException(entity.getMessage(), entity.getErrorCode()); - } else { - throw new ExternalSurveillanceToolException(entity.getMessage()); - } +// ExternalSurveillanceToolResponse entity = response.readEntity(ExternalSurveillanceToolResponse.class); +// if (entity == null || StringUtils.isBlank(entity.getMessage())) { +// throw new ExternalSurveillanceToolException( +// I18nProperties.getString(Strings.ExternalSurveillanceToolGateway_notificationErrorSending)); +// } else if (StringUtils.isNotBlank(entity.getErrorCode())) { +// throw new ExternalSurveillanceToolException(entity.getMessage(), entity.getErrorCode()); +// } else { +// throw new ExternalSurveillanceToolException(entity.getMessage()); +// } } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseContactsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseContactsView.java index 4f76337cd3a..f35d2916655 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseContactsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseContactsView.java @@ -254,11 +254,11 @@ public HorizontalLayout createStatusFilterBar() { }), new MenuBarHelper.MenuBarItem(I18nProperties.getCaption(Captions.bulkCancelFollowUp), VaadinIcons.CLOSE, selectedItem -> { ControllerProvider.getContactController() - .cancelFollowUpOfAllSelectedItems(grid.asMultiSelect().getSelectedItems(), () -> navigateTo(criteria)); + .cancelFollowUpOfAllSelectedItems(grid.asMultiSelect().getSelectedItems(), getCaseRef().getUuid(), grid); }), new MenuBarHelper.MenuBarItem(I18nProperties.getCaption(Captions.bulkLostToFollowUp), VaadinIcons.UNLINK, selectedItem -> { ControllerProvider.getContactController() - .setAllSelectedItemsToLostToFollowUp(grid.asMultiSelect().getSelectedItems(), () -> navigateTo(criteria)); + .setAllSelectedItemsToLostToFollowUp(grid.asMultiSelect().getSelectedItems(), getCaseRef().getUuid(), grid); }), new MenuBarHelper.MenuBarItem(I18nProperties.getCaption(Captions.bulkDelete), VaadinIcons.TRASH, selectedItem -> { ControllerProvider.getContactController() diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java index 4b51f517efd..90ef3e56fb2 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java @@ -1044,30 +1044,30 @@ public void showBulkCaseDataEditComponent(Collection 500, e -> BulkOperationHandler. forBulkEdit() .doBulkOperation( - selectedEntries -> caseFacade.saveBulkEditWithFacilities( + selectedEntries -> caseFacade.saveBulkEditWithFacilities( + selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList()), + updatedBulkEditData, + diseaseChange, + classificationChange, + investigationStatusChange, + outcomeChange, + surveillanceOfficerChange, + e), + selectedCasesCpy, + bulkOperationCallback(caseGrid, popupWindow))); + } else { + BulkOperationHandler. forBulkEdit() + .doBulkOperation( + selectedEntries -> caseFacade.saveBulkCase( selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList()), updatedBulkEditData, diseaseChange, classificationChange, investigationStatusChange, outcomeChange, - surveillanceOfficerChange, - e), + surveillanceOfficerChange), selectedCasesCpy, - bulkOperationCallback(caseGrid, popupWindow))); - } else { - BulkOperationHandler. forBulkEdit() - .doBulkOperation( - selectedEntries -> caseFacade.saveBulkCase( - selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList()), - updatedBulkEditData, - diseaseChange, - classificationChange, - investigationStatusChange, - outcomeChange, - surveillanceOfficerChange), - selectedCasesCpy, - bulkOperationCallback(caseGrid, popupWindow)); + bulkOperationCallback(caseGrid, popupWindow)); } }); @@ -1702,11 +1702,10 @@ public TitleLayout getCaseViewTitleLayout(CaseDataDto caseData) { return titleLayout; } - public void sendCasesToExternalSurveillanceTool(Collection selectedCases, Runnable reloadCallback) { - List selectedUuids = selectedCases.stream().map(CaseIndexDto::getUuid).collect(Collectors.toList()); + public void sendCasesToExternalSurveillanceTool(Collection selectedCases, AbstractCaseGrid caseGrid) { // Show an error when at least one selected case is not a CORONAVIRUS case - Optional nonCoronavirusCase = selectedCases.stream().filter(c -> c.getDisease() != Disease.CORONAVIRUS).findFirst(); + Optional nonCoronavirusCase = selectedCases.stream().filter(c -> c.getDisease() != Disease.CORONAVIRUS).findFirst(); if (nonCoronavirusCase.isPresent()) { Notification.show( String.format( @@ -1719,11 +1718,11 @@ public void sendCasesToExternalSurveillanceTool(Collection selectedUuids = selectedCases.stream().map(CaseIndexDto::getUuid).collect(Collectors.toList()); List notSharableUuids = FacadeProvider.getCaseFacade().getUuidsNotShareableWithExternalReportingTools(selectedUuids); if (CollectionUtils.isNotEmpty(notSharableUuids)) { - List uuidsWithoutNotShareable = - selectedUuids.stream().filter(uuid -> !notSharableUuids.contains(uuid)).collect(Collectors.toList()); + List withoutNotShareable = selectedCases.stream().filter(c -> !notSharableUuids.contains(c.getUuid())).collect(Collectors.toList()); TextArea notShareableListComponent = new TextArea("", new ArrayList<>(notSharableUuids).toString()); notShareableListComponent.setWidthFull(); @@ -1732,11 +1731,11 @@ public void sendCasesToExternalSurveillanceTool(Collection { if (confirmed) { - ExternalSurveillanceServiceGateway.sendCasesToExternalSurveillanceTool(uuidsWithoutNotShareable, reloadCallback, false); + ExternalSurveillanceServiceGateway + .sendCasesToExternalSurveillanceTool(withoutNotShareable, false, bulkOperationCallback(caseGrid, null)); } }); } } else { - ExternalSurveillanceServiceGateway.sendCasesToExternalSurveillanceTool(selectedUuids, reloadCallback, true); + ExternalSurveillanceServiceGateway.sendCasesToExternalSurveillanceTool(selectedCases, true, bulkOperationCallback(caseGrid, null)); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasesView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasesView.java index aa25a7d16a4..30d50355477 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasesView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasesView.java @@ -775,8 +775,8 @@ public HorizontalLayout createStatusFilterBar() { showNoCasesSelectedWarning(caseGrid); return; } - ControllerProvider.getCaseController().sendCasesToExternalSurveillanceTool(items, () -> navigateTo(criteria)); + ControllerProvider.getCaseController().sendCasesToExternalSurveillanceTool(items, (AbstractCaseGrid) grid); }); }, FacadeProvider.getExternalSurveillanceToolFacade().isFeatureEnabled())); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactController.java index 1cd1a418ced..7aba2634d23 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactController.java @@ -765,13 +765,13 @@ public void showBulkContactDataEditComponent( List selectedContactsCpy = new ArrayList<>(selectedContacts); BulkOperationHandler. forBulkEdit() .doBulkOperation( - selectedEntries -> contactFacade.saveBulkContacts( - selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList()), - updatedBulkEditData, - classificationChange, - contactOfficerChange), - selectedContactsCpy, - bulkOperationCallback(caseUuid, contactGrid, popupWindow)); + selectedEntries -> contactFacade.saveBulkContacts( + selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList()), + updatedBulkEditData, + classificationChange, + contactOfficerChange), + selectedContactsCpy, + bulkOperationCallback(caseUuid, contactGrid, popupWindow)); }); editView.addDiscardListener(popupWindow::close); @@ -836,9 +836,12 @@ public void restoreSelectedContacts(Collection select callback); } - public void cancelFollowUpOfAllSelectedItems(Collection selectedRows, Runnable callback) { + public void cancelFollowUpOfAllSelectedItems( + Collection selectedRows, + String caseUuid, + AbstractContactGrid contactGrid) { - if (selectedRows.size() == 0) { + if (selectedRows.isEmpty()) { new Notification( I18nProperties.getString(Strings.headingNoContactsSelected), I18nProperties.getString(Strings.messageNoContactsSelected), @@ -852,30 +855,33 @@ public void cancelFollowUpOfAllSelectedItems(Collection { - if (confirmed) { - for (ContactIndexDto contact : selectedRows) { - if (!FollowUpStatus.NO_FOLLOW_UP.equals(contact.getFollowUpStatus()) - && !FollowUpStatus.CANCELED.equals(contact.getFollowUpStatus())) { - ContactDto contactDto = FacadeProvider.getContactFacade().getByUuid(contact.getUuid()); - contactDto.setFollowUpStatus(FollowUpStatus.CANCELED); - contactDto.addToFollowUpComment( - String.format(I18nProperties.getString(Strings.infoCanceledBy), UserProvider.getCurrent().getUserName())); - FacadeProvider.getContactFacade().save(contactDto); - } - } - callback.run(); - new Notification( - I18nProperties.getString(Strings.headingFollowUpCanceled), - I18nProperties.getString(Strings.messageFollowUpCanceled), - Type.HUMANIZED_MESSAGE, - false).show(Page.getCurrent()); + if (Boolean.TRUE.equals(confirmed)) { + String userName = UserProvider.getCurrent().getUserName(); + + new BulkOperationHandler(Strings.messageFollowUpCanceled, Strings.messageFollowUpCanceledForSome) + .doBulkOperation(batch -> { + for (ContactIndexDto contact : batch) { + if (!FollowUpStatus.NO_FOLLOW_UP.equals(contact.getFollowUpStatus()) + && !FollowUpStatus.CANCELED.equals(contact.getFollowUpStatus())) { + ContactDto contactDto = FacadeProvider.getContactFacade().getByUuid(contact.getUuid()); + contactDto.setFollowUpStatus(FollowUpStatus.CANCELED); + contactDto.addToFollowUpComment(String.format(I18nProperties.getString(Strings.infoCanceledBy), userName)); + FacadeProvider.getContactFacade().save(contactDto); + } + } + + return batch.size(); + }, new ArrayList<>(selectedRows), bulkOperationCallback(caseUuid, contactGrid, null)); } }); } } - public void setAllSelectedItemsToLostToFollowUp(Collection selectedRows, Runnable callback) { - if (selectedRows.size() == 0) { + public void setAllSelectedItemsToLostToFollowUp( + Collection selectedRows, + String caseUuid, + AbstractContactGrid contactGrid) { + if (selectedRows.isEmpty()) { new Notification( I18nProperties.getString(Strings.headingNoContactsSelected), I18nProperties.getString(Strings.messageNoContactsSelected), @@ -889,22 +895,23 @@ public void setAllSelectedItemsToLostToFollowUp(Collection { - if (confirmed) { - for (ContactIndexDto contact : selectedRows) { - if (contact.getFollowUpStatus() != FollowUpStatus.NO_FOLLOW_UP) { - ContactDto contactDto = FacadeProvider.getContactFacade().getByUuid(contact.getUuid()); - contactDto.setFollowUpStatus(FollowUpStatus.LOST); - contactDto.addToFollowUpComment( - String.format(I18nProperties.getString(Strings.infoLostToFollowUpBy), UserProvider.getCurrent().getUserName())); - FacadeProvider.getContactFacade().save(contactDto); - } - } - callback.run(); - new Notification( - I18nProperties.getString(Strings.headingFollowUpStatusChanged), - I18nProperties.getString(Strings.messageFollowUpStatusChanged), - Type.HUMANIZED_MESSAGE, - false).show(Page.getCurrent()); + if (Boolean.TRUE.equals(confirmed)) { + String userName = UserProvider.getCurrent().getUserName(); + + new BulkOperationHandler(Strings.messageFollowUpStatusChanged, Strings.messageFollowUpStatusChangedForSome) + .doBulkOperation(batch -> { + for (ContactIndexDto contact : batch) { + if (contact.getFollowUpStatus() != FollowUpStatus.NO_FOLLOW_UP) { + ContactDto contactDto = FacadeProvider.getContactFacade().getByUuid(contact.getUuid()); + contactDto.setFollowUpStatus(FollowUpStatus.LOST); + contactDto + .addToFollowUpComment(String.format(I18nProperties.getString(Strings.infoLostToFollowUpBy), userName)); + FacadeProvider.getContactFacade().save(contactDto); + } + } + + return batch.size(); + }, new ArrayList<>(selectedRows), bulkOperationCallback(caseUuid, contactGrid, null)); } }); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsView.java index 47566bafa42..73b82c4476e 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsView.java @@ -523,14 +523,14 @@ public HorizontalLayout createStatusFilterBar() { VaadinIcons.CLOSE, mi -> grid.bulkActionHandler( items -> ControllerProvider.getContactController() - .cancelFollowUpOfAllSelectedItems(items, () -> navigateTo(criteria))), + .cancelFollowUpOfAllSelectedItems(items, null, (AbstractContactGrid) grid)), hasBulkOperationsRight), new MenuBarHelper.MenuBarItem( I18nProperties.getCaption(Captions.bulkLostToFollowUp), VaadinIcons.UNLINK, mi -> grid.bulkActionHandler( items -> ControllerProvider.getContactController() - .setAllSelectedItemsToLostToFollowUp(items, () -> navigateTo(criteria))), + .setAllSelectedItemsToLostToFollowUp(items, null, (AbstractContactGrid) grid)), hasBulkOperationsRight), criteria.getRelevanceStatus() != EntityRelevanceStatus.DELETED ? new MenuBarHelper.MenuBarItem( diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventController.java index 29725a299a3..25a3c967a4d 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventController.java @@ -970,14 +970,14 @@ public void showBulkEventDataEditComponent(Collection selectedEve List selectedEventsCpy = new ArrayList<>(selectedEvents); BulkOperationHandler. forBulkEdit() .doBulkOperation( - selectedEntries -> eventFacade.saveBulkEvents( - selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList()), - updatedTempEvent, - eventStatusChange, - eventInvestigationStatusChange, - eventManagementStatusChange), - selectedEventsCpy, - bulkOperationCallback(eventGrid, popupWindow)); + selectedEntries -> eventFacade.saveBulkEvents( + selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList()), + updatedTempEvent, + eventStatusChange, + eventInvestigationStatusChange, + eventManagementStatusChange), + selectedEventsCpy, + bulkOperationCallback(eventGrid, popupWindow)); }); editView.addDiscardListener(popupWindow::close); @@ -1136,9 +1136,7 @@ public TitleLayout getEventViewTitleLayout(String uuid) { return titleLayout; } - public void sendAllSelectedToExternalSurveillanceTool(Set selectedRows, Runnable callback) { - List selectedUuids = selectedRows.stream().map(EventIndexDto::getUuid).collect(Collectors.toList()); - + public void sendAllSelectedToExternalSurveillanceTool(Set selectedRows, EventGrid eventGrid) { // Show an error when at least one selected event is not a CLUSTER event Optional nonClusterEvent = selectedRows.stream().filter(e -> e.getEventStatus() != EventStatus.CLUSTER).findFirst(); if (nonClusterEvent.isPresent()) { @@ -1153,10 +1151,11 @@ public void sendAllSelectedToExternalSurveillanceTool(Set selecte } // Show an error when at least one selected event is not owned by this server because ownership has been handed over + List selectedUuids = selectedRows.stream().map(EventIndexDto::getUuid).collect(Collectors.toList()); List ownershipHandedOverUuids = FacadeProvider.getEventFacade().getEventUuidsWithOwnershipHandedOver(selectedUuids); if (CollectionUtils.isNotEmpty(ownershipHandedOverUuids)) { - List uuidsWithoutNotSharable = - selectedUuids.stream().filter(uuid -> !ownershipHandedOverUuids.contains(uuid)).collect(Collectors.toList()); + List withoutNotSharable = + selectedRows.stream().filter(e -> !ownershipHandedOverUuids.contains(e.getUuid())).collect(Collectors.toList()); TextArea notShareableListComponent = new TextArea("", new ArrayList<>(ownershipHandedOverUuids).toString()); notShareableListComponent.setWidthFull(); @@ -1170,17 +1169,22 @@ public void sendAllSelectedToExternalSurveillanceTool(Set selecte new VerticalLayout(notSharableLabel, notShareableListComponent), String.format( I18nProperties.getCaption(Captions.ExternalSurveillanceToolGateway_excludeAndSend), - uuidsWithoutNotSharable.size(), - selectedUuids.size()), + withoutNotSharable.size(), + selectedRows.size()), I18nProperties.getCaption(Captions.actionCancel), 800, (confirmed) -> { if (confirmed) { - ExternalSurveillanceServiceGateway.sendEventsToExternalSurveillanceTool(selectedUuids, callback, false); + ExternalSurveillanceServiceGateway + .sendEventsToExternalSurveillanceTool(withoutNotSharable, false, bulkOperationCallback(eventGrid, null)); } }); } else { - ExternalSurveillanceServiceGateway.sendEventsToExternalSurveillanceTool(selectedUuids, callback, true); + ExternalSurveillanceServiceGateway.sendEventsToExternalSurveillanceTool(selectedRows, true, bulkOperationCallback(eventGrid, null)); } } + + public void linkAllToGroup(Set selectedItems) { + ControllerProvider.getEventGroupController().linkAllToGroup(selectedItems); + } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventGroupController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventGroupController.java index 521625fdd8c..63d810cb16c 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventGroupController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventGroupController.java @@ -20,6 +20,7 @@ import java.util.Collections; import java.util.List; import java.util.Set; +import java.util.function.Consumer; import java.util.stream.Collectors; import com.vaadin.server.Page; @@ -52,6 +53,7 @@ import de.symeda.sormas.ui.UserProvider; import de.symeda.sormas.ui.events.groups.EventGroupSelectionField; import de.symeda.sormas.ui.utils.ArchivingController; +import de.symeda.sormas.ui.utils.BulkOperationHandler; import de.symeda.sormas.ui.utils.ButtonHelper; import de.symeda.sormas.ui.utils.CommitDiscardWrapperComponent; import de.symeda.sormas.ui.utils.VaadinUiUtil; @@ -118,14 +120,6 @@ public void select(List eventReferences, Runnable callback) { if (selectedEventGroup != null) { FacadeProvider.getEventGroupFacade().linkEventsToGroup(eventReferences, selectedEventGroup.toReference()); FacadeProvider.getEventGroupFacade().notifyEventAddedToEventGroup(selectedEventGroup.toReference(), eventReferences); - - Notification.show(I18nProperties.getString(Strings.messageEventLinkedToGroup), Type.TRAY_NOTIFICATION); - - if (callback != null) { - callback.run(); - } else { - SormasUI.refreshView(); - } } }); @@ -137,7 +131,7 @@ public void selectOrCreate(EventReferenceDto eventReference) { selectOrCreate(Collections.singletonList(eventReference), null); } - public void selectOrCreate(List eventReferences, Runnable callback) { + public void selectOrCreate(List eventReferences, Consumer callback) { Set excludedEventGroupUuids = FacadeProvider.getEventGroupFacade() .getCommonEventGroupsByEvents(eventReferences) .stream() @@ -150,8 +144,13 @@ public void selectOrCreate(List eventReferences, Runnable cal component.addCommitListener(() -> { EventGroupIndexDto selectedEventGroup = selectionField.getValue(); if (selectedEventGroup != null) { - FacadeProvider.getEventGroupFacade().linkEventsToGroup(eventReferences, selectedEventGroup.toReference()); - FacadeProvider.getEventGroupFacade().notifyEventAddedToEventGroup(selectedEventGroup.toReference(), eventReferences); + new BulkOperationHandler(Strings.messageEventsLinkedToGroup, Strings.messageSomeEventsLinkedToGroup) + .doBulkOperation(batch -> { + FacadeProvider.getEventGroupFacade().linkEventsToGroup(batch, selectedEventGroup.toReference()); + FacadeProvider.getEventGroupFacade().notifyEventAddedToEventGroup(selectedEventGroup.toReference(), batch); + + return batch.size(); + }, eventReferences, callback); Notification.show(I18nProperties.getString(Strings.messageEventLinkedToGroup), Type.TRAY_NOTIFICATION); @@ -341,7 +340,7 @@ private void archiveOrDearchiveEventGroup(String uuid, boolean archive) { } } - public void linkAllToGroup(Set selectedItems, Runnable callback) { + public void linkAllToGroup(Set selectedItems) { if (selectedItems.size() == 0) { new Notification( I18nProperties.getString(Strings.headingNoEventsSelected), diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventsView.java index 201a64f6249..07b5592fcd2 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventsView.java @@ -587,8 +587,7 @@ public HorizontalLayout createStatusFilterBar() { I18nProperties.getCaption(Captions.actionGroupEvent), VaadinIcons.FILE_TREE, mi -> grid.bulkActionHandler( - items -> ControllerProvider.getEventGroupController() - .linkAllToGroup(eventGrid.asMultiSelect().getSelectedItems(), () -> navigateTo(eventCriteria))))); + items -> ControllerProvider.getEventController().linkAllToGroup(eventGrid.asMultiSelect().getSelectedItems())))); } bulkActions.add( new MenuBarHelper.MenuBarItem( @@ -596,9 +595,7 @@ public HorizontalLayout createStatusFilterBar() { VaadinIcons.SHARE, mi -> grid.bulkActionHandler( items -> ControllerProvider.getEventController() - .sendAllSelectedToExternalSurveillanceTool( - eventGrid.asMultiSelect().getSelectedItems(), - () -> navigateTo(eventCriteria))), + .sendAllSelectedToExternalSurveillanceTool(eventGrid.asMultiSelect().getSelectedItems(), eventGrid)), FacadeProvider.getExternalSurveillanceToolFacade().isFeatureEnabled())); if (isDocGenerationAllowed()) { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalsurveillanceservice/ExternalSurveillanceServiceGateway.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalsurveillanceservice/ExternalSurveillanceServiceGateway.java index 1d83bbbcaef..57e09ebcbbb 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalsurveillanceservice/ExternalSurveillanceServiceGateway.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalsurveillanceservice/ExternalSurveillanceServiceGateway.java @@ -1,7 +1,11 @@ package de.symeda.sormas.ui.externalsurveillanceservice; +import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Collectors; import javax.annotation.Nullable; @@ -14,13 +18,16 @@ import de.symeda.sormas.api.FacadeProvider; import de.symeda.sormas.api.caze.CaseDataDto; +import de.symeda.sormas.api.caze.CaseIndexDto; import de.symeda.sormas.api.event.EventDto; +import de.symeda.sormas.api.event.EventIndexDto; import de.symeda.sormas.api.externalsurveillancetool.ExternalSurveillanceToolException; import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.i18n.Strings; import de.symeda.sormas.api.share.ExternalShareInfoCriteria; import de.symeda.sormas.ui.SormasUI; +import de.symeda.sormas.ui.utils.BulkOperationHandler; import de.symeda.sormas.ui.utils.DirtyStateComponent; import de.symeda.sormas.ui.utils.LayoutWithSidePanel; import de.symeda.sormas.ui.utils.VaadinUiUtil; @@ -96,8 +103,8 @@ private static ExternalSurveillanceShareComponent addComponentToLayout( confirmationText, gatewaySendCall, I18nProperties.getString(Strings.ExternalSurveillanceToolGateway_notificationEntrySent), - SormasUI::refreshView, - true); + true, + SormasUI::refreshView); } : null, gatewayDeleteCall != null ? () -> { deleteInExternalSurveillanceTool(deletionText, gatewayDeleteCall, SormasUI::refreshView); } : null, shareInfoCriteria, editComponent); @@ -106,27 +113,60 @@ private static ExternalSurveillanceShareComponent addComponentToLayout( return shareComponent; } - public static void sendCasesToExternalSurveillanceTool(List uuids, Runnable callback, boolean shouldConfirm) { + public static void sendCasesToExternalSurveillanceTool( + Collection selectedCases, + boolean shouldConfirm, + Consumer> callback) { sendToExternalSurveillanceTool(I18nProperties.getString(Strings.ExternalSurveillanceToolGateway_confirmSendCases), () -> { - FacadeProvider.getExternalSurveillanceToolFacade().sendCases(uuids); - }, I18nProperties.getString(Strings.ExternalSurveillanceToolGateway_notificationEntriesSent), callback, shouldConfirm); + ArrayList selectedCasesCpy = new ArrayList<>(selectedCases); + new BulkOperationHandler( + Strings.ExternalSurveillanceToolGateway_notificationEntriesSent, + Strings.ExternalSurveillanceToolGateway_notificationSomeEntriesSent).doBulkOperation(batch -> { + try { + FacadeProvider.getExternalSurveillanceToolFacade() + .sendCases(batch.stream().map(CaseIndexDto::getUuid).collect(Collectors.toList())); + } catch (ExternalSurveillanceToolException e) { + return 0; + } + + return batch.size(); + }, selectedCasesCpy, callback); + + }, null, shouldConfirm, null); } - public static void sendEventsToExternalSurveillanceTool(List uuids, Runnable callback, boolean shouldConfirm) { + public static void sendEventsToExternalSurveillanceTool( + Collection selectedEvents, + boolean shouldConfirm, + Consumer> callback) { sendToExternalSurveillanceTool(I18nProperties.getString(Strings.ExternalSurveillanceToolGateway_confirmSendEvents), () -> { - FacadeProvider.getExternalSurveillanceToolFacade().sendEvents(uuids); - }, I18nProperties.getString(Strings.ExternalSurveillanceToolGateway_notificationEntriesSent), callback, shouldConfirm); + ArrayList selectedEventsCpy = new ArrayList<>(selectedEvents); + new BulkOperationHandler( + Strings.ExternalSurveillanceToolGateway_notificationEntriesSent, + Strings.ExternalSurveillanceToolGateway_notificationSomeEntriesSent).doBulkOperation(batch -> { + try { + FacadeProvider.getExternalSurveillanceToolFacade() + .sendEvents(batch.stream().map(EventIndexDto::getUuid).collect(Collectors.toList())); + } catch (ExternalSurveillanceToolException e) { + return 0; + } + + return batch.size(); + }, selectedEventsCpy, callback); + }, null, shouldConfirm, null); } private static void sendToExternalSurveillanceTool( String confirmationText, GatewayCall gatewayCall, String successMessage, - Runnable callback, - boolean shouldConfirm) { + boolean shouldConfirm, + Runnable callback) { Runnable doSend = () -> { handleGatewayCall(gatewayCall, successMessage); - callback.run(); + if (callback != null) { + callback.run(); + } }; if (shouldConfirm) { VaadinUiUtil.showConfirmationPopup( @@ -145,7 +185,7 @@ private static void sendToExternalSurveillanceTool( } } - private static void handleGatewayCall(GatewayCall gatewayCall, String successMessage) { + private static void handleGatewayCall(GatewayCall gatewayCall, @Nullable String successMessage) { Notification.Type notificationType; String notificationMessage; @@ -153,8 +193,12 @@ private static void handleGatewayCall(GatewayCall gatewayCall, String successMes try { gatewayCall.call(); - notificationType = Notification.Type.HUMANIZED_MESSAGE; - notificationMessage = successMessage; + if (successMessage != null) { + Notification.show( + I18nProperties.getCaption(Captions.ExternalSurveillanceToolGateway_title), + successMessage, + Notification.Type.HUMANIZED_MESSAGE); + } } catch (ExternalSurveillanceToolException e) { if (StringUtils.isNotBlank(e.getErrorCode()) && "timeout_anticipated".equals(e.getErrorCode())) { notificationType = Notification.Type.WARNING_MESSAGE; @@ -162,9 +206,9 @@ private static void handleGatewayCall(GatewayCall gatewayCall, String successMes notificationType = Notification.Type.ERROR_MESSAGE; } notificationMessage = e.getMessage(); - } - Notification.show(I18nProperties.getCaption(Captions.ExternalSurveillanceToolGateway_title), notificationMessage, notificationType); + Notification.show(I18nProperties.getCaption(Captions.ExternalSurveillanceToolGateway_title), notificationMessage, notificationType); + } } public static void deleteInExternalSurveillanceTool(String deletionText, GatewayCall gatewayCall, Runnable callback) { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/BulkOperationHandler.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/BulkOperationHandler.java index b4d8ba3ef43..35ede43629f 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/BulkOperationHandler.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/BulkOperationHandler.java @@ -7,6 +7,8 @@ import java.util.function.Consumer; import java.util.function.Function; +import org.slf4j.LoggerFactory; + import com.vaadin.server.Sizeable; import com.vaadin.ui.Label; import com.vaadin.ui.Notification; @@ -117,8 +119,14 @@ public void doBulkOperation( } }); - } catch (InterruptedException e) { - throw new RuntimeException(e); + } catch (Exception e) { + LoggerFactory.getLogger(BulkOperationHandler.class).error("Error during bulk operation", e); + bulkProgressLayout.finishProgress(ProgressResult.FAILURE, I18nProperties.getString(Strings.errorWasReported), () -> { + window.close(); + bulkOperationDoneCallback.accept(selectedEntries); + }); + } finally { + currentUI.setPollInterval(-1); } }); From 107a6a3986ad028512739b5b183b926ba09c4ae8 Mon Sep 17 00:00:00 2001 From: Levente Gal Date: Wed, 5 Jul 2023 14:55:01 +0300 Subject: [PATCH 005/174] #11464 Add bulk action progress window to all bulk actions except "Edit", "Archive" and "Delete" - event and user bulk actions --- .../sormas/api/event/EventGroupFacade.java | 5 +- .../de/symeda/sormas/api/i18n/Strings.java | 4 +- .../src/main/resources/strings.properties | 4 +- .../backend/event/EventGroupFacadeEjb.java | 56 ++++++++------ .../sormas/ui/events/EventController.java | 4 +- .../ui/events/EventGroupController.java | 77 ++++++++++--------- .../symeda/sormas/ui/events/EventsView.java | 3 +- .../symeda/sormas/ui/user/UserController.java | 57 ++++++++------ .../de/symeda/sormas/ui/user/UsersView.java | 4 +- 9 files changed, 123 insertions(+), 91 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/event/EventGroupFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/event/EventGroupFacade.java index ef137c65130..3e9d1ae96a1 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/event/EventGroupFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/event/EventGroupFacade.java @@ -18,6 +18,7 @@ package de.symeda.sormas.api.event; import java.util.List; +import java.util.Set; import javax.ejb.Remote; import javax.validation.Valid; @@ -58,7 +59,7 @@ Page getIndexPage( void linkEventsToGroup(List eventReferences, EventGroupReferenceDto eventGroupReference); - void linkEventsToGroups(List eventReferences, List eventGroupReferences); + void linkEventsToGroups(List eventUuids, List eventGroupReferences); void unlinkEventGroup(EventReferenceDto eventReference, EventGroupReferenceDto eventGroupReference); @@ -72,5 +73,7 @@ Page getIndexPage( void notifyEventAddedToEventGroup(EventGroupReferenceDto eventGroupReference, List eventReferences); + void notifyEventAddedToEventGroup(String eventGroupUuid, Set eventUuids); + void notifyEventRemovedFromEventGroup(EventGroupReferenceDto eventGroupReference, List eventReferences); } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java index 9885ea64efa..33051a44fbf 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java @@ -746,8 +746,6 @@ public interface Strings { String headingUpdatePersonContactDetails = "headingUpdatePersonContactDetails"; String headingUploadSuccess = "headingUploadSuccess"; String headingUserData = "headingUserData"; - String headingUsersDisabled = "headingUsersDisabled"; - String headingUsersEnabled = "headingUsersEnabled"; String headingUserSettings = "headingUserSettings"; String headingVaccination = "headingVaccination"; String headingViewAdditionalTest = "headingViewAdditionalTest"; @@ -1268,6 +1266,8 @@ public interface Strings { String messageSomeEntitiesArchived = "messageSomeEntitiesArchived"; String messageSomeEntitiesDearchived = "messageSomeEntitiesDearchived"; String messageSomeEventsLinkedToGroup = "messageSomeEventsLinkedToGroup"; + String messageSomeUsersDisabled = "messageSomeUsersDisabled"; + String messageSomeUsersEnabled = "messageSomeUsersEnabled"; String messageSormasToSormasSimilarCaseFound = "messageSormasToSormasSimilarCaseFound"; String messageSormasToSormasSimilarCaseToContactFound = "messageSormasToSormasSimilarCaseToContactFound"; String messageSormasToSormasSimilarContactFound = "messageSormasToSormasSimilarContactFound"; diff --git a/sormas-api/src/main/resources/strings.properties b/sormas-api/src/main/resources/strings.properties index ef3c646ef5f..8f6c9d0693d 100644 --- a/sormas-api/src/main/resources/strings.properties +++ b/sormas-api/src/main/resources/strings.properties @@ -750,8 +750,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -1302,7 +1300,9 @@ messageExternalMessagesDeleted = All selected messages have been deleted messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventGroupFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventGroupFacadeEjb.java index dd0aa079e0f..cee7c9e9b66 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventGroupFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventGroupFacadeEjb.java @@ -351,30 +351,31 @@ public void linkEventToGroup(EventReferenceDto eventReference, EventGroupReferen @Override @RightsAllowed(UserRight._EVENTGROUP_LINK) public void linkEventsToGroup(List eventReferences, EventGroupReferenceDto eventGroupReference) { - linkEventsToGroups(eventReferences, Collections.singletonList(eventGroupReference)); + linkEventsToGroups( + eventReferences.stream().map(EventReferenceDto::getUuid).collect(Collectors.toList()), + Collections.singletonList(eventGroupReference.getUuid())); } @Override @RightsAllowed(UserRight._EVENTGROUP_LINK) public void linkEventToGroups(EventReferenceDto eventReference, List eventGroupReferences) { - linkEventsToGroups(Collections.singletonList(eventReference), eventGroupReferences); + linkEventsToGroups( + Collections.singletonList(eventReference.getUuid()), + eventGroupReferences.stream().map(EventGroupReferenceDto::getUuid).collect(Collectors.toList())); } @Override @RightsAllowed(UserRight._EVENTGROUP_LINK) - public void linkEventsToGroups(List eventReferences, List eventGroupReferences) { - User currentUser = userService.getCurrentUser(); - - if (CollectionUtils.isEmpty(eventReferences)) { + public void linkEventsToGroups(List eventUuids, List eventGroupUuids) { + if (CollectionUtils.isEmpty(eventGroupUuids) || CollectionUtils.isEmpty(eventUuids)) { return; } - List eventUuids = eventReferences.stream().map(EventReferenceDto::getUuid).collect(Collectors.toList()); List events = eventService.getByUuids(eventUuids); - - List eventGroupUuids = eventGroupReferences.stream().map(EventGroupReferenceDto::getUuid).collect(Collectors.toList()); List eventGroups = eventGroupService.getByUuids(eventGroupUuids); + User currentUser = userService.getCurrentUser(); + for (Event event : events) { final JurisdictionLevel jurisdictionLevel = currentUser.getJurisdictionLevel(); if (!eventFacade.isInJurisdictionOrOwned(event.getUuid()) && (jurisdictionLevel != JurisdictionLevel.NATION) && !currentUser.isAdmin()) { @@ -508,8 +509,8 @@ public List getEventGroupRelatedRegions(String uuid) { @RightsAllowed(UserRight._EVENTGROUP_CREATE) public void notifyEventEventGroupCreated(EventGroupReferenceDto eventGroupReference) { notifyModificationOfEventGroup( - eventGroupReference, - Collections.emptyList(), + eventGroupReference.getUuid(), + Collections.emptySet(), NotificationType.EVENT_GROUP_CREATED, MessageSubject.EVENT_GROUP_CREATED, MessageContents.CONTENT_EVENT_GROUP_CREATED); @@ -519,8 +520,19 @@ public void notifyEventEventGroupCreated(EventGroupReferenceDto eventGroupRefere @RightsAllowed(UserRight._EVENTGROUP_LINK) public void notifyEventAddedToEventGroup(EventGroupReferenceDto eventGroupReference, List eventReferences) { notifyModificationOfEventGroup( - eventGroupReference, - eventReferences, + eventGroupReference.getUuid(), + eventReferences.stream().map(EventReferenceDto::getUuid).collect(Collectors.toSet()), + NotificationType.EVENT_ADDED_TO_EVENT_GROUP, + MessageSubject.EVENT_ADDED_TO_EVENT_GROUP, + MessageContents.CONTENT_EVENT_ADDED_TO_EVENT_GROUP); + } + + @Override + @RightsAllowed(UserRight._EVENTGROUP_LINK) + public void notifyEventAddedToEventGroup(String eventGroupUuid, Set eventUuids) { + notifyModificationOfEventGroup( + eventGroupUuid, + eventUuids, NotificationType.EVENT_ADDED_TO_EVENT_GROUP, MessageSubject.EVENT_ADDED_TO_EVENT_GROUP, MessageContents.CONTENT_EVENT_ADDED_TO_EVENT_GROUP); @@ -530,20 +542,20 @@ public void notifyEventAddedToEventGroup(EventGroupReferenceDto eventGroupRefere @RightsAllowed(UserRight._EVENTGROUP_LINK) public void notifyEventRemovedFromEventGroup(EventGroupReferenceDto eventGroupReference, List eventReferences) { notifyModificationOfEventGroup( - eventGroupReference, - eventReferences, + eventGroupReference.getUuid(), + eventReferences.stream().map(EventReferenceDto::getUuid).collect(Collectors.toSet()), NotificationType.EVENT_REMOVED_FROM_EVENT_GROUP, MessageSubject.EVENT_REMOVED_FROM_EVENT_GROUP, MessageContents.CONTENT_EVENT_REMOVED_FROM_EVENT_GROUP); } private void notifyModificationOfEventGroup( - EventGroupReferenceDto eventGroupReference, - List impactedEventReferences, + String eventGroupUuid, + Set impactedEventUuids, NotificationType notificationType, MessageSubject subject, String contentTemplate) { - EventGroup eventGroup = eventGroupService.getByUuid(eventGroupReference.getUuid()); + EventGroup eventGroup = eventGroupService.getByUuid(eventGroupUuid); if (eventGroup == null) { return; } @@ -553,10 +565,8 @@ private void notifyModificationOfEventGroup( try { notificationService.sendNotifications(notificationType, subject, () -> { - final Set allRemainingEventUuids = getEventReferencesByEventGroupUuid(eventGroupReference.getUuid()).stream() - .map(EventReferenceDto::getUuid) - .collect(Collectors.toSet()); - final Set impactedEventUuids = impactedEventReferences.stream().map(EventReferenceDto::getUuid).collect(Collectors.toSet()); + final Set allRemainingEventUuids = + getEventReferencesByEventGroupUuid(eventGroupUuid).stream().map(EventReferenceDto::getUuid).collect(Collectors.toSet()); final Map responsibleUserByEventUuid = userService.getResponsibleUsersByEventUuids(new ArrayList<>(Sets.union(allRemainingEventUuids, impactedEventUuids))); @@ -566,7 +576,7 @@ private void notifyModificationOfEventGroup( Maps.filterKeys(responsibleUserByEventUuid, impactedEventUuids::contains); final String message; - if (impactedEventReferences.isEmpty()) { + if (impactedEventUuids.isEmpty()) { message = String.format( I18nProperties.getString(contentTemplate), eventGroup.getName(), diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventController.java index 25a3c967a4d..2c78aebfa52 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventController.java @@ -1184,7 +1184,7 @@ public void sendAllSelectedToExternalSurveillanceTool(Set selecte } } - public void linkAllToGroup(Set selectedItems) { - ControllerProvider.getEventGroupController().linkAllToGroup(selectedItems); + public void linkAllToGroup(Set selectedItems, EventGrid eventGrid) { + ControllerProvider.getEventGroupController().linkAllToGroup(selectedItems, bulkOperationCallback(eventGrid, null)); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventGroupController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventGroupController.java index 63d810cb16c..91709108e92 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventGroupController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventGroupController.java @@ -17,6 +17,7 @@ *******************************************************************************/ package de.symeda.sormas.ui.events; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; @@ -61,6 +62,26 @@ public class EventGroupController { + private static void linkEventsToGroup( + List eventReferences, + EventGroupReferenceDto eventGroupReference, + Consumer> callback) { + + String messageEventsLinkedToGroup = eventReferences.size() > 1 ? Strings.messageEventsLinkedToGroup : Strings.messageEventLinkedToGroup; + new BulkOperationHandler(messageEventsLinkedToGroup, Strings.messageSomeEventsLinkedToGroup).doBulkOperation(batch -> { + FacadeProvider.getEventGroupFacade() + .linkEventsToGroups( + batch.stream().map(EventReferenceDto::getUuid).collect(Collectors.toList()), + Collections.singletonList(eventGroupReference.getUuid())); + FacadeProvider.getEventGroupFacade() + .notifyEventAddedToEventGroup( + eventGroupReference.getUuid(), + batch.stream().map(EventReferenceDto::getUuid).collect(Collectors.toSet())); + + return batch.size(); + }, new ArrayList<>(eventReferences), callback); + } + public void create(EventReferenceDto eventReference) { EventDto eventByUuid = FacadeProvider.getEventFacade().getEventByUuid(eventReference.getUuid(), false); @@ -78,7 +99,7 @@ public void create(EventReferenceDto eventReference) { if (events > 0) { ControllerProvider.getEventGroupController().selectOrCreate(eventReference); } else { - ControllerProvider.getEventGroupController().create(Collections.singletonList(eventReference), null); + ControllerProvider.getEventGroupController().create(Collections.singletonList(eventReference), (r) -> SormasUI.refreshView()); } } else { long events = FacadeProvider.getEventGroupFacade().count(eventGroupCriteria); @@ -94,7 +115,7 @@ public void create(EventReferenceDto eventReference) { } } - public EventGroupDto create(List events, Runnable callback) { + public EventGroupDto create(List events, Consumer> callback) { CommitDiscardWrapperComponent eventCreateComponent = getEventGroupCreateComponent(events, callback); EventGroupDto eventGroupDto = eventCreateComponent.getWrappedComponent().getValue(); VaadinUiUtil.showModalPopupWindow(eventCreateComponent, I18nProperties.getString(Strings.headingCreateNewEventGroup)); @@ -102,10 +123,10 @@ public EventGroupDto create(List events, Runnable callback) { } public void select(EventReferenceDto eventReference) { - select(Collections.singletonList(eventReference), null); + select(Collections.singletonList(eventReference), (r) -> SormasUI.refreshView()); } - public void select(List eventReferences, Runnable callback) { + public void select(List eventReferences, Consumer> callback) { Set excludedEventGroupUuids = FacadeProvider.getEventGroupFacade() .getCommonEventGroupsByEvents(eventReferences) .stream() @@ -118,8 +139,7 @@ public void select(List eventReferences, Runnable callback) { component.addCommitListener(() -> { EventGroupIndexDto selectedEventGroup = selectionField.getValue(); if (selectedEventGroup != null) { - FacadeProvider.getEventGroupFacade().linkEventsToGroup(eventReferences, selectedEventGroup.toReference()); - FacadeProvider.getEventGroupFacade().notifyEventAddedToEventGroup(selectedEventGroup.toReference(), eventReferences); + linkEventsToGroup(eventReferences, selectedEventGroup.toReference(), callback); } }); @@ -128,10 +148,10 @@ public void select(List eventReferences, Runnable callback) { } public void selectOrCreate(EventReferenceDto eventReference) { - selectOrCreate(Collections.singletonList(eventReference), null); + selectOrCreate(Collections.singletonList(eventReference), (r) -> SormasUI.refreshView()); } - public void selectOrCreate(List eventReferences, Consumer callback) { + public void selectOrCreate(List eventReferences, Consumer> callback) { Set excludedEventGroupUuids = FacadeProvider.getEventGroupFacade() .getCommonEventGroupsByEvents(eventReferences) .stream() @@ -144,21 +164,7 @@ public void selectOrCreate(List eventReferences, Consumer { EventGroupIndexDto selectedEventGroup = selectionField.getValue(); if (selectedEventGroup != null) { - new BulkOperationHandler(Strings.messageEventsLinkedToGroup, Strings.messageSomeEventsLinkedToGroup) - .doBulkOperation(batch -> { - FacadeProvider.getEventGroupFacade().linkEventsToGroup(batch, selectedEventGroup.toReference()); - FacadeProvider.getEventGroupFacade().notifyEventAddedToEventGroup(selectedEventGroup.toReference(), batch); - - return batch.size(); - }, eventReferences, callback); - - Notification.show(I18nProperties.getString(Strings.messageEventLinkedToGroup), Type.TRAY_NOTIFICATION); - - if (callback != null) { - callback.run(); - } else { - SormasUI.refreshView(); - } + linkEventsToGroup(eventReferences, selectedEventGroup.toReference(), callback); } else { create(eventReferences, callback); } @@ -174,7 +180,7 @@ public EventGroupDto createNewEventGroup() { public CommitDiscardWrapperComponent getEventGroupCreateComponent( List eventReferences, - Runnable callback) { + Consumer> callback) { EventGroupDataForm createForm = new EventGroupDataForm(true); createForm.setValue(createNewEventGroup()); @@ -188,15 +194,9 @@ public CommitDiscardWrapperComponent getEventGroupCreateComp EventGroupDto dto = createForm.getValue(); EventGroupFacade eventGroupFacade = FacadeProvider.getEventGroupFacade(); dto = eventGroupFacade.saveEventGroup(dto); - eventGroupFacade.linkEventsToGroup(eventReferences, dto.toReference()); - eventGroupFacade.notifyEventEventGroupCreated(dto.toReference()); Notification.show(I18nProperties.getString(Strings.messageEventGroupCreated), Type.WARNING_MESSAGE); - if (callback != null) { - callback.run(); - } else { - SormasUI.refreshView(); - } + linkEventsToGroup(eventReferences, dto.toReference(), callback); } }); @@ -340,7 +340,7 @@ private void archiveOrDearchiveEventGroup(String uuid, boolean archive) { } } - public void linkAllToGroup(Set selectedItems) { + public void linkAllToGroup(Set selectedItems, Consumer> callback) { if (selectedItems.size() == 0) { new Notification( I18nProperties.getString(Strings.headingNoEventsSelected), @@ -375,19 +375,24 @@ public void linkAllToGroup(Set selectedItems) { .map(EventGroupReferenceDto::getUuid) .collect(Collectors.toSet()); eventGroupCriteria.setExcludedUuids(eventGroupUuids); + Consumer> callbackWrapper = remainingReferences -> callback.accept( + selectedItems.stream() + .filter(e -> remainingReferences.stream().anyMatch(r -> r.getUuid().equals(e.getUuid()))) + .collect(Collectors.toList())); + if (user.hasUserRight(UserRight.EVENTGROUP_CREATE) && user.hasUserRight(UserRight.EVENTGROUP_LINK)) { long eventCount = FacadeProvider.getEventGroupFacade().count(eventGroupCriteria); if (eventCount > 0) { - selectOrCreate(eventReferences, null); + selectOrCreate(eventReferences, callbackWrapper); } else { - create(eventReferences, null); + create(eventReferences, callbackWrapper); } } else if (user.hasUserRight(UserRight.EVENTGROUP_CREATE)) { - create(eventReferences, null); + create(eventReferences, callbackWrapper); } else { long eventCount = FacadeProvider.getEventGroupFacade().count(eventGroupCriteria); if (eventCount > 0) { - select(eventReferences, null); + select(eventReferences, callbackWrapper); } else { new Notification( I18nProperties.getString(Strings.headingEventGroupLinkEventIssue), diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventsView.java index 07b5592fcd2..1d7d2de5309 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventsView.java @@ -587,7 +587,8 @@ public HorizontalLayout createStatusFilterBar() { I18nProperties.getCaption(Captions.actionGroupEvent), VaadinIcons.FILE_TREE, mi -> grid.bulkActionHandler( - items -> ControllerProvider.getEventController().linkAllToGroup(eventGrid.asMultiSelect().getSelectedItems())))); + items -> ControllerProvider.getEventController() + .linkAllToGroup(eventGrid.asMultiSelect().getSelectedItems(), eventGrid)))); } bulkActions.add( new MenuBarHelper.MenuBarItem( diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserController.java index 98313e6646b..c0be526e89d 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserController.java @@ -17,12 +17,14 @@ *******************************************************************************/ package de.symeda.sormas.ui.user; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; import java.util.function.Consumer; import java.util.stream.Collectors; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import com.vaadin.icons.VaadinIcons; @@ -54,6 +56,7 @@ import de.symeda.sormas.api.utils.DataHelper; import de.symeda.sormas.ui.SormasUI; import de.symeda.sormas.ui.UserProvider; +import de.symeda.sormas.ui.utils.BulkOperationHandler; import de.symeda.sormas.ui.utils.ButtonHelper; import de.symeda.sormas.ui.utils.CommitDiscardWrapperComponent; import de.symeda.sormas.ui.utils.CommitDiscardWrapperComponent.CommitListener; @@ -344,9 +347,9 @@ public void sync() { window.setCaption(I18nProperties.getCaption(Captions.syncUsers)); } - public void enableAllSelectedItems(Collection selectedRows, Runnable callback) { + public void enableAllSelectedItems(Collection selectedRows, UserGrid userGrid) { - if (selectedRows.size() == 0) { + if (selectedRows.isEmpty()) { new Notification( I18nProperties.getString(Strings.headingNoUsersSelected), I18nProperties.getString(Strings.messageNoUsersSelected), @@ -360,25 +363,30 @@ public void enableAllSelectedItems(Collection selectedRows, Runnable ca I18nProperties.getString(Strings.no), null, confirmed -> { - if (!confirmed) { + if (Boolean.FALSE.equals(confirmed)) { return; } - List uuids = selectedRows.stream().map(UserDto::getUuid).collect(Collectors.toList()); - FacadeProvider.getUserFacade().enableUsers(uuids); - callback.run(); - new Notification( - I18nProperties.getString(Strings.headingUsersEnabled), - I18nProperties.getString(Strings.messageUsersEnabled), - Notification.Type.HUMANIZED_MESSAGE, - false).show(Page.getCurrent()); + new BulkOperationHandler(Strings.messageUsersEnabled, Strings.messageSomeUsersEnabled).doBulkOperation(batch -> { + List uuids = batch.stream().map(UserDto::getUuid).collect(Collectors.toList()); + FacadeProvider.getUserFacade().enableUsers(uuids); + + return batch.size(); + }, new ArrayList<>(selectedRows), remaining -> { + userGrid.reload(); + if (CollectionUtils.isNotEmpty(remaining)) { + userGrid.asMultiSelect().selectItems(remaining.toArray(new UserDto[0])); + } else { + overview(); + } + }); }); } } - public void disableAllSelectedItems(Collection selectedRows, Runnable callback) { + public void disableAllSelectedItems(Collection selectedRows, UserGrid userGrid) { - if (selectedRows.size() == 0) { + if (selectedRows.isEmpty()) { new Notification( I18nProperties.getString(Strings.headingNoUsersSelected), I18nProperties.getString(Strings.messageNoUsersSelected), @@ -392,18 +400,23 @@ public void disableAllSelectedItems(Collection selectedRows, Runnable c I18nProperties.getString(Strings.no), null, confirmed -> { - if (!confirmed) { + if (Boolean.FALSE.equals(confirmed)) { return; } - List uuids = selectedRows.stream().map(UserDto::getUuid).collect(Collectors.toList()); - FacadeProvider.getUserFacade().disableUsers(uuids); - callback.run(); - new Notification( - I18nProperties.getString(Strings.headingUsersDisabled), - I18nProperties.getString(Strings.messageUsersDisabled), - Notification.Type.HUMANIZED_MESSAGE, - false).show(Page.getCurrent()); + new BulkOperationHandler(Strings.messageUsersDisabled, Strings.messageSomeUsersDisabled).doBulkOperation(batch -> { + List uuids = batch.stream().map(UserDto::getUuid).collect(Collectors.toList()); + FacadeProvider.getUserFacade().disableUsers(uuids); + + return batch.size(); + }, new ArrayList<>(selectedRows), remaining -> { + userGrid.reload(); + if (CollectionUtils.isNotEmpty(remaining)) { + userGrid.asMultiSelect().selectItems(remaining.toArray(new UserDto[0])); + } else { + overview(); + } + }); }); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UsersView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UsersView.java index d3fceff67da..b1d615fda26 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UsersView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UsersView.java @@ -255,11 +255,11 @@ public HorizontalLayout createActionsBar() { Captions.bulkActions, new MenuBarHelper.MenuBarItem(I18nProperties.getCaption(Captions.actionEnable), VaadinIcons.CHECK_SQUARE_O, selectedItem -> { ControllerProvider.getUserController() - .enableAllSelectedItems(grid.asMultiSelect().getSelectedItems(), () -> navigateTo(criteria)); + .enableAllSelectedItems(grid.asMultiSelect().getSelectedItems(), grid); }, true), new MenuBarHelper.MenuBarItem(I18nProperties.getCaption(Captions.actionDisable), VaadinIcons.THIN_SQUARE, selectedItem -> { ControllerProvider.getUserController() - .disableAllSelectedItems(grid.asMultiSelect().getSelectedItems(), () -> navigateTo(criteria)); + .disableAllSelectedItems(grid.asMultiSelect().getSelectedItems(), grid); }, true)); bulkOperationsDropdown.setVisible(ViewModelProviders.of(UsersView.class).get(ViewConfiguration.class).isInEagerMode()); From 4ac8508a75d5ff97f0a655d728f9b96ab354dd49 Mon Sep 17 00:00:00 2001 From: Levente Gal Date: Wed, 5 Jul 2023 23:13:58 +0300 Subject: [PATCH 006/174] #11464 Add bulk action progress window to all bulk actions except "Edit", "Archive" and "Delete" - revert commented code --- ...ernalSurveillanceToolGatewayFacadeEjb.java | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/externalsurveillancetool/ExternalSurveillanceToolGatewayFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/externalsurveillancetool/ExternalSurveillanceToolGatewayFacadeEjb.java index 9a5be0f82f3..4d40083fd70 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/externalsurveillancetool/ExternalSurveillanceToolGatewayFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/externalsurveillancetool/ExternalSurveillanceToolGatewayFacadeEjb.java @@ -30,6 +30,7 @@ import javax.ws.rs.client.Invocation; import javax.ws.rs.core.Response; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -124,15 +125,14 @@ private void doSendEvents(List eventUuids, boolean archived) throws Exte private void sendRequest(ExportParameters params) throws ExternalSurveillanceToolException { String serviceUrl = configFacade.getExternalSurveillanceToolGatewayUrl().trim(); -// Response response = ClientBuilder.newBuilder() -// .connectTimeout(30, TimeUnit.SECONDS) -// .build() -// .target(serviceUrl) -// .path("export") -// .request() -// .post(Entity.json(params)); -// int status = response.getStatus(); - int status = HttpServletResponse.SC_OK; + Response response = ClientBuilder.newBuilder() + .connectTimeout(30, TimeUnit.SECONDS) + .build() + .target(serviceUrl) + .path("export") + .request() + .post(Entity.json(params)); + int status = response.getStatus(); switch (status) { case HttpServletResponse.SC_OK: @@ -152,15 +152,15 @@ private void sendRequest(ExportParameters params) throws ExternalSurveillanceToo case HttpServletResponse.SC_BAD_REQUEST: throw new ExternalSurveillanceToolException(I18nProperties.getString(Strings.ExternalSurveillanceToolGateway_notificationEntryNotSent)); default: -// ExternalSurveillanceToolResponse entity = response.readEntity(ExternalSurveillanceToolResponse.class); -// if (entity == null || StringUtils.isBlank(entity.getMessage())) { -// throw new ExternalSurveillanceToolException( -// I18nProperties.getString(Strings.ExternalSurveillanceToolGateway_notificationErrorSending)); -// } else if (StringUtils.isNotBlank(entity.getErrorCode())) { -// throw new ExternalSurveillanceToolException(entity.getMessage(), entity.getErrorCode()); -// } else { -// throw new ExternalSurveillanceToolException(entity.getMessage()); -// } + ExternalSurveillanceToolResponse entity = response.readEntity(ExternalSurveillanceToolResponse.class); + if (entity == null || StringUtils.isBlank(entity.getMessage())) { + throw new ExternalSurveillanceToolException( + I18nProperties.getString(Strings.ExternalSurveillanceToolGateway_notificationErrorSending)); + } else if (StringUtils.isNotBlank(entity.getErrorCode())) { + throw new ExternalSurveillanceToolException(entity.getMessage(), entity.getErrorCode()); + } else { + throw new ExternalSurveillanceToolException(entity.getMessage()); + } } } From 5bd019c63c09cf9a7afa4a4491c0f5b936665d45 Mon Sep 17 00:00:00 2001 From: Levente Gal Date: Thu, 6 Jul 2023 01:18:47 +0300 Subject: [PATCH 007/174] #11464 Add bulk action progress window to all bulk actions except "Edit", "Archive" and "Delete" - link contacts to event --- .../api/event/EventParticipantFacade.java | 2 +- .../de/symeda/sormas/api/i18n/Strings.java | 1 + .../src/main/resources/strings.properties | 1 + .../sormas/backend/common/BaseAdoService.java | 2 +- .../event/EventParticipantFacadeEjb.java | 2 +- .../sormas/ui/contact/ContactController.java | 25 +++++ .../sormas/ui/contact/ContactsView.java | 28 +----- .../sormas/ui/events/EventController.java | 92 ++++++++++--------- .../sormas/ui/utils/BulkOperationHandler.java | 26 +++--- 9 files changed, 95 insertions(+), 84 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/event/EventParticipantFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/event/EventParticipantFacade.java index 61219e28305..0497c368502 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/event/EventParticipantFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/event/EventParticipantFacade.java @@ -71,7 +71,7 @@ List getExportList( List getByPersonUuids(List personUuids); - List getByEventAndPersons(String eventUuid, Collection personUuids); + List getByEventAndPersons(String eventUuid, List personUuids); List getEventParticipantsWithSameEvent(String firstPersonUuid, String secondPersonUuid); } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java index 33051a44fbf..c234558ae04 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java @@ -1263,6 +1263,7 @@ public interface Strings { String messageSamplesRestored = "messageSamplesRestored"; String messageSelectedPeriodTooLong = "messageSelectedPeriodTooLong"; String messageSetContactRegionAndDistrict = "messageSetContactRegionAndDistrict"; + String messageSomeContactsLinkedToEvent = "messageSomeContactsLinkedToEvent"; String messageSomeEntitiesArchived = "messageSomeEntitiesArchived"; String messageSomeEntitiesDearchived = "messageSomeEntitiesDearchived"; String messageSomeEventsLinkedToGroup = "messageSomeEventsLinkedToGroup"; diff --git a/sormas-api/src/main/resources/strings.properties b/sormas-api/src/main/resources/strings.properties index 8f6c9d0693d..c64f5fabf1a 100644 --- a/sormas-api/src/main/resources/strings.properties +++ b/sormas-api/src/main/resources/strings.properties @@ -993,6 +993,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/BaseAdoService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/BaseAdoService.java index 358a9a18ed4..23656435a68 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/BaseAdoService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/BaseAdoService.java @@ -376,7 +376,7 @@ protected EntityGraph getEntityFetchGraph() { return entityGraph; } - public List getByUuids(List uuids) { + public List getByUuids(Collection uuids) { if (uuids == null || uuids.isEmpty()) { return null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java index 66e2cdbe4a3..10c0a121a49 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java @@ -1223,7 +1223,7 @@ public List getByPersonUuids(List personUuids) { } @Override - public List getByEventAndPersons(String eventUuid, Collection personUuids) { + public List getByEventAndPersons(String eventUuid, List personUuids) { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cq = cb.createQuery(EventParticipant.class); Root eventParticipantRoot = cq.from(EventParticipant.class); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactController.java index 7aba2634d23..06434e3ae55 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactController.java @@ -1013,4 +1013,29 @@ public TitleLayout getContactViewTitleLayout(ContactDto contact) { return titleLayout; } + + public void linkSelectedContactsToEvent(Collection selectedRows, AbstractContactGrid contactGrid) { + if (selectedRows.isEmpty()) { + new Notification( + I18nProperties.getString(Strings.headingNoContactsSelected), + I18nProperties.getString(Strings.messageNoContactsSelected), + Notification.Type.WARNING_MESSAGE, + false).show(Page.getCurrent()); + return; + } + + if (!selectedRows.stream().allMatch(contact -> contact.getDisease().equals(selectedRows.stream().findAny().get().getDisease()))) { + new Notification(I18nProperties.getString(Strings.messageBulkContactsWithDifferentDiseasesSelected), Notification.Type.WARNING_MESSAGE) + .show(Page.getCurrent()); + return; + } + + ControllerProvider.getEventController() + .selectOrCreateEventForContactList(selectedRows.stream().map(ContactIndexDto::toReference).collect(Collectors.toList()), remaining -> { + bulkOperationCallback(null, contactGrid, null).accept( + selectedRows.stream() + .filter(s -> remaining.stream().anyMatch(r -> r.getUuid().equals(s.getUuid()))) + .collect(Collectors.toList())); + }); + } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsView.java index 73b82c4476e..fb3e04d33b0 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsView.java @@ -602,31 +602,9 @@ public HorizontalLayout createStatusFilterBar() { new MenuBarHelper.MenuBarItem( I18nProperties.getCaption(Captions.bulkLinkToEvent), VaadinIcons.PHONE, - mi -> grid.bulkActionHandler(items -> { - List selectedContacts = - grid.asMultiSelect().getSelectedItems().stream().map(item -> (ContactIndexDto) item).collect(Collectors.toList()); - - if (selectedContacts.isEmpty()) { - new Notification( - I18nProperties.getString(Strings.headingNoContactsSelected), - I18nProperties.getString(Strings.messageNoContactsSelected), - Notification.Type.WARNING_MESSAGE, - false).show(Page.getCurrent()); - return; - } - - if (!selectedContacts.stream() - .allMatch(contact -> contact.getDisease().equals(selectedContacts.stream().findAny().get().getDisease()))) { - new Notification( - I18nProperties.getString(Strings.messageBulkContactsWithDifferentDiseasesSelected), - Notification.Type.WARNING_MESSAGE).show(Page.getCurrent()); - return; - } - - ControllerProvider.getEventController() - .selectOrCreateEventForContactList( - selectedContacts.stream().map(ContactIndexDto::toReference).collect(Collectors.toList())); - }))); + mi -> grid.bulkActionHandler( + items -> ControllerProvider.getContactController() + .linkSelectedContactsToEvent(items, (AbstractContactGrid) grid)))); } bulkOperationsDropdown = MenuBarHelper.createDropDown(Captions.bulkActions, bulkActions); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventController.java index 2c78aebfa52..90f29b1baa5 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventController.java @@ -32,6 +32,7 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; +import com.google.common.base.Functions; import com.vaadin.navigator.Navigator; import com.vaadin.server.Page; import com.vaadin.server.Sizeable; @@ -45,6 +46,7 @@ import com.vaadin.ui.Window; import de.symeda.sormas.api.Disease; +import de.symeda.sormas.api.EntityDto; import de.symeda.sormas.api.FacadeProvider; import de.symeda.sormas.api.ReferenceDto; import de.symeda.sormas.api.caze.CaseDataDto; @@ -71,6 +73,7 @@ import de.symeda.sormas.api.person.PersonDto; import de.symeda.sormas.api.person.PersonReferenceDto; import de.symeda.sormas.api.user.UserDto; +import de.symeda.sormas.api.user.UserReferenceDto; import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.api.utils.DataHelper; import de.symeda.sormas.api.utils.HtmlHelper; @@ -126,8 +129,8 @@ public EventDto create(ContactDto contact) { return eventDto; } - public EventDto createFromContactList(List contactRefs) { - CommitDiscardWrapperComponent eventCreateComponent = getEventCreateComponentForContactList(contactRefs); + public EventDto createFromContactList(List contactRefs, Consumer> callback) { + CommitDiscardWrapperComponent eventCreateComponent = getEventCreateComponentForContactList(contactRefs, callback); EventDto eventDto = eventCreateComponent.getWrappedComponent().getValue(); VaadinUiUtil.showModalPopupWindow(eventCreateComponent, I18nProperties.getString(Strings.headingCreateNewEvent)); return eventDto; @@ -228,7 +231,7 @@ public void selectOrCreateEventForCaseList(List caseRefs) { VaadinUiUtil.showModalPopupWindow(component, I18nProperties.getString(Strings.headingPickOrCreateEvent)); } - public void selectOrCreateEventForContactList(List contactRefs) { + public void selectOrCreateEventForContactList(List contactRefs, Consumer> callback) { if (contactRefs == null || contactRefs.isEmpty()) { return; @@ -248,9 +251,12 @@ public void selectOrCreateEventForContactList(List contactR EventIndexDto selectedEvent = eventSelect.getValue(); if (selectedEvent != null) { EventReferenceDto eventReferenceDto = new EventReferenceDto(selectedEvent.getUuid()); - linkContactsToEvent(eventReferenceDto, contactDtos); + linkContactsToEvent( + eventReferenceDto, + contactDtos, + remaining -> callback.accept(remaining.stream().map(ContactDto::toReference).collect(Collectors.toList()))); } else { - createFromContactList(contactRefs); + createFromContactList(contactRefs, callback); SormasUI.refreshView(); } }); @@ -317,51 +323,43 @@ private void linkCasesToEvent(EventReferenceDto eventReferenceDto, List contacts) { + private void linkContactsToEvent(EventReferenceDto eventReferenceDto, List contacts, Consumer> callback) { - Map contactByPersonUuid = new HashMap<>(); + Map contactByPersonUuid = + contacts.stream().collect(Collectors.toMap(c -> c.getPerson().getUuid(), Functions.identity(), (c1, c2) -> c1)); - List personUuids = contacts.stream().map(contactDataDto -> { - String personUuid = contactDataDto.getPerson().getUuid(); - if (!contactByPersonUuid.containsKey(personUuid)) { - contactByPersonUuid.put(personUuid, contactDataDto); - } - return personUuid; - }).collect(Collectors.toList()); + List byEventAndPersons = FacadeProvider.getEventParticipantFacade() + .getByEventAndPersons(eventReferenceDto.getUuid(), new ArrayList<>(contactByPersonUuid.keySet())); + byEventAndPersons.forEach(eventParticipant -> contactByPersonUuid.remove(eventParticipant.getPerson().getUuid())); - FacadeProvider.getEventParticipantFacade() - .getByEventAndPersons(eventReferenceDto.getUuid(), personUuids) - .stream() - .forEach(eventParticipant -> contactByPersonUuid.remove(eventParticipant.getPerson().getUuid())); + if (contactByPersonUuid.isEmpty()) { + NotificationHelper.showNotification(I18nProperties.getString(Strings.messageAllContactsAlreadyInEvent), Type.HUMANIZED_MESSAGE, 10000); - Collection remainingContacts = contactByPersonUuid.values(); - int contactsAlreadyLinkedToEvent = contacts.size() - remainingContacts.size(); + return; + } //Create EventParticipants for the remaining contacts - if (!remainingContacts.isEmpty()) { - List remainingPersonUuids = - remainingContacts.stream().map(caseDataDto -> caseDataDto.getPerson().getUuid()).collect(Collectors.toList()); - List remainingPersons = FacadeProvider.getPersonFacade().getByUuids(remainingPersonUuids); - HashMap personByUuid = new HashMap<>(); - remainingPersons.stream().forEach(personDto -> personByUuid.put(personDto.getUuid(), personDto)); - remainingContacts.stream().forEach(contactDataDto -> { - EventParticipantDto ep = EventParticipantDto.buildFromPerson( - personByUuid.get(contactDataDto.getPerson().getUuid()), - eventReferenceDto, - UserProvider.getCurrent().getUserReference()); - FacadeProvider.getEventParticipantFacade().save(ep); - }); - } + List remainingPersons = FacadeProvider.getPersonFacade().getByUuids(new ArrayList<>(contactByPersonUuid.keySet())); + Map personByUuid = remainingPersons.stream().collect(Collectors.toMap(EntityDto::getUuid, Functions.identity())); - String message = remainingContacts.isEmpty() - ? I18nProperties.getString(Strings.messageAllContactsAlreadyInEvent) - : contactsAlreadyLinkedToEvent == 0 - ? I18nProperties.getString(Strings.messageAllContactsLinkedToEvent) - : String.format(I18nProperties.getString(Strings.messageCountContactsAlreadyInEvent), contactsAlreadyLinkedToEvent); + int contactsAlreadyLinkedToEvent = contacts.size() - contactByPersonUuid.size(); + String allLinkedMessage = contactsAlreadyLinkedToEvent == 0 + ? I18nProperties.getString(Strings.messageAllContactsLinkedToEvent) + : String.format(I18nProperties.getString(Strings.messageCountContactsAlreadyInEvent), contactsAlreadyLinkedToEvent); - SormasUI.refreshView(); - NotificationHelper.showNotification(message, Type.HUMANIZED_MESSAGE, 10000); + UserReferenceDto currentUser = UserProvider.getCurrent().getUserReference(); + + new BulkOperationHandler(allLinkedMessage, I18nProperties.getString(Strings.messageSomeContactsLinkedToEvent), true) + .doBulkOperation(batch -> { + batch.forEach(contactDataDto -> { + EventParticipantDto ep = + EventParticipantDto.buildFromPerson(personByUuid.get(contactDataDto.getPerson().getUuid()), eventReferenceDto, currentUser); + FacadeProvider.getEventParticipantFacade().save(ep); + }); + + return batch.size(); + }, new ArrayList<>(contactByPersonUuid.values()), callback); } public void selectEvent(EventGroupReferenceDto eventGroupReference) { @@ -712,10 +710,12 @@ public CommitDiscardWrapperComponent getEventCreateComponentForCa return editView; } - public CommitDiscardWrapperComponent getEventCreateComponentForContactList(List contactRefs) { + public CommitDiscardWrapperComponent getEventCreateComponentForContactList( + List contactRefs, + Consumer> callback) { List contactDtos = - FacadeProvider.getContactFacade().getByUuids(contactRefs.stream().map(c -> c.getUuid()).collect(Collectors.toList())); + FacadeProvider.getContactFacade().getByUuids(contactRefs.stream().map(ReferenceDto::getUuid).collect(Collectors.toList())); EventDataForm eventCreateForm = new EventDataForm(true, false, true); // Valid because jurisdiction doesn't matter for entities that are about to be created eventCreateForm.setValue(createNewEvent(contactDtos.stream().findFirst().get().getDisease())); @@ -725,14 +725,16 @@ public CommitDiscardWrapperComponent getEventCreateComponentForCo UserProvider.getCurrent().hasUserRight(UserRight.EVENT_CREATE), eventCreateForm.getFieldGroup()); - List finalContactDtos = contactDtos; editView.addCommitListener(() -> { if (!eventCreateForm.getFieldGroup().isModified()) { EventDto dto = eventCreateForm.getValue(); FacadeProvider.getEventFacade().save(dto); Notification.show(I18nProperties.getString(Strings.messageEventCreated), Type.WARNING_MESSAGE); - linkContactsToEvent(new EventReferenceDto(dto.getUuid()), finalContactDtos); + linkContactsToEvent( + new EventReferenceDto(dto.getUuid()), + contactDtos, + remaining -> callback.accept(remaining.stream().map(ContactDto::toReference).collect(Collectors.toList()))); } }); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/BulkOperationHandler.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/BulkOperationHandler.java index 35ede43629f..8fbdd727f9b 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/BulkOperationHandler.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/BulkOperationHandler.java @@ -42,16 +42,23 @@ public class BulkOperationHandler { private int initialEntryCount; private int successfulEntryCount; - private final String allEntriesProcessedMessageProperty; - private final String someEntriesProcessedMessageProperty; + private final String allEntriesProcessedMessage; + private final String someEntriesProcessedMessage; + + private boolean messagesTranslated; public BulkOperationHandler(String allEntriesProcessedMessageProperty, String someEntriesProcessedMessageProperty) { - this.allEntriesProcessedMessageProperty = allEntriesProcessedMessageProperty; - this.someEntriesProcessedMessageProperty = someEntriesProcessedMessageProperty; + this.allEntriesProcessedMessage = I18nProperties.getString(allEntriesProcessedMessageProperty); + this.someEntriesProcessedMessage = I18nProperties.getString(someEntriesProcessedMessageProperty); + } + + public BulkOperationHandler(String allEntriesProcessedMessage, String someEntriesProcessedMessage, boolean messagesTranslated) { + this.allEntriesProcessedMessage = messagesTranslated ? allEntriesProcessedMessage : I18nProperties.getString(allEntriesProcessedMessage); + this.someEntriesProcessedMessage = messagesTranslated ? someEntriesProcessedMessage : I18nProperties.getString(someEntriesProcessedMessage); } public static BulkOperationHandler forBulkEdit() { - return new BulkOperationHandler(Strings.messageEntriesEdited, Strings.messageEntriesEditedExceptArchived); + return new BulkOperationHandler<>(Strings.messageEntriesEdited, Strings.messageEntriesEditedExceptArchived); } public void doBulkOperation( @@ -63,13 +70,10 @@ public void doBulkOperation( if (selectedEntries.size() < BULK_ACTION_PROGRESS_THRESHOLD) { successfulEntryCount = bulkOperationFunction.apply(selectedEntries); if (initialEntryCount > successfulEntryCount) { - NotificationHelper.showNotification( - String.format(I18nProperties.getString(someEntriesProcessedMessageProperty), successfulEntryCount), - Notification.Type.HUMANIZED_MESSAGE, - -1); - } else { NotificationHelper - .showNotification(I18nProperties.getString(allEntriesProcessedMessageProperty), Notification.Type.HUMANIZED_MESSAGE, -1); + .showNotification(String.format(someEntriesProcessedMessage, successfulEntryCount), Notification.Type.HUMANIZED_MESSAGE, -1); + } else { + NotificationHelper.showNotification(allEntriesProcessedMessage, Notification.Type.HUMANIZED_MESSAGE, -1); } bulkOperationDoneCallback.accept(Collections.emptyList()); } else { From 8322d1da4655cb6e2bded1eb0c5f9bd95487127a Mon Sep 17 00:00:00 2001 From: jenkins Date: Mon, 10 Jul 2023 12:10:09 +0200 Subject: [PATCH 008/174] [GITFLOW]updating poms for 1.87.0-SNAPSHOT development --- sormas-api/pom.xml | 2 +- sormas-app/pom.xml | 2 +- sormas-backend/pom.xml | 2 +- sormas-base/pom.xml | 2 +- sormas-cargoserver/pom.xml | 2 +- sormas-ear/pom.xml | 2 +- sormas-keycloak-service-provider/pom.xml | 2 +- sormas-rest/pom.xml | 2 +- sormas-serverlibs/pom.xml | 2 +- sormas-ui/pom.xml | 2 +- sormas-widgetset/pom.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/sormas-api/pom.xml b/sormas-api/pom.xml index e794ce13ded..eb1b1b89a83 100644 --- a/sormas-api/pom.xml +++ b/sormas-api/pom.xml @@ -2,7 +2,7 @@ de.symeda.sormas sormas-base - 1.86.0-SNAPSHOT + 1.87.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-app/pom.xml b/sormas-app/pom.xml index 4518f37d747..f0b488d93bb 100644 --- a/sormas-app/pom.xml +++ b/sormas-app/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.86.0-SNAPSHOT + 1.87.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-backend/pom.xml b/sormas-backend/pom.xml index 42b04ef13f7..999e5717002 100644 --- a/sormas-backend/pom.xml +++ b/sormas-backend/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.86.0-SNAPSHOT + 1.87.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index 14f5abbfc30..def4aff04f5 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -5,7 +5,7 @@ de.symeda.sormas sormas-base pom - 1.86.0-SNAPSHOT + 1.87.0-SNAPSHOT 3.6.3 diff --git a/sormas-cargoserver/pom.xml b/sormas-cargoserver/pom.xml index 5fcf0067597..b01dc9b18a5 100644 --- a/sormas-cargoserver/pom.xml +++ b/sormas-cargoserver/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.86.0-SNAPSHOT + 1.87.0-SNAPSHOT ../sormas-base diff --git a/sormas-ear/pom.xml b/sormas-ear/pom.xml index b6ed586e568..2b6d48f1228 100644 --- a/sormas-ear/pom.xml +++ b/sormas-ear/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.86.0-SNAPSHOT + 1.87.0-SNAPSHOT ../sormas-base diff --git a/sormas-keycloak-service-provider/pom.xml b/sormas-keycloak-service-provider/pom.xml index 53be2702b15..35cf0fc8dd9 100644 --- a/sormas-keycloak-service-provider/pom.xml +++ b/sormas-keycloak-service-provider/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.86.0-SNAPSHOT + 1.87.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-rest/pom.xml b/sormas-rest/pom.xml index 395c95d88cf..e8c54fe44cc 100644 --- a/sormas-rest/pom.xml +++ b/sormas-rest/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.86.0-SNAPSHOT + 1.87.0-SNAPSHOT ../sormas-base diff --git a/sormas-serverlibs/pom.xml b/sormas-serverlibs/pom.xml index 334858a87a9..e803227c873 100644 --- a/sormas-serverlibs/pom.xml +++ b/sormas-serverlibs/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.86.0-SNAPSHOT + 1.87.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-ui/pom.xml b/sormas-ui/pom.xml index 5684645f6bf..9bdf3c48466 100644 --- a/sormas-ui/pom.xml +++ b/sormas-ui/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.86.0-SNAPSHOT + 1.87.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-widgetset/pom.xml b/sormas-widgetset/pom.xml index cf5fd419710..2e65f34fbde 100644 --- a/sormas-widgetset/pom.xml +++ b/sormas-widgetset/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.86.0-SNAPSHOT + 1.87.0-SNAPSHOT ../sormas-base 4.0.0 From bf0c9dfcf5905e18b21171611570fd4a95d9d2f0 Mon Sep 17 00:00:00 2001 From: jenkins Date: Mon, 10 Jul 2023 12:32:13 +0200 Subject: [PATCH 009/174] [GITFLOW]updating develop poms to master versions to avoid merge conflicts --- sormas-api/pom.xml | 2 +- sormas-app/pom.xml | 2 +- sormas-backend/pom.xml | 2 +- sormas-base/pom.xml | 2 +- sormas-cargoserver/pom.xml | 2 +- sormas-ear/pom.xml | 2 +- sormas-keycloak-service-provider/pom.xml | 2 +- sormas-rest/pom.xml | 2 +- sormas-serverlibs/pom.xml | 2 +- sormas-ui/pom.xml | 2 +- sormas-widgetset/pom.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/sormas-api/pom.xml b/sormas-api/pom.xml index eb1b1b89a83..89b8368cc31 100644 --- a/sormas-api/pom.xml +++ b/sormas-api/pom.xml @@ -2,7 +2,7 @@ de.symeda.sormas sormas-base - 1.87.0-SNAPSHOT + 1.86.0 ../sormas-base 4.0.0 diff --git a/sormas-app/pom.xml b/sormas-app/pom.xml index f0b488d93bb..be59506bd8d 100644 --- a/sormas-app/pom.xml +++ b/sormas-app/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.87.0-SNAPSHOT + 1.86.0 ../sormas-base 4.0.0 diff --git a/sormas-backend/pom.xml b/sormas-backend/pom.xml index 999e5717002..b69378095e9 100644 --- a/sormas-backend/pom.xml +++ b/sormas-backend/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.87.0-SNAPSHOT + 1.86.0 ../sormas-base 4.0.0 diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index def4aff04f5..a480f1137fb 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -5,7 +5,7 @@ de.symeda.sormas sormas-base pom - 1.87.0-SNAPSHOT + 1.86.0 3.6.3 diff --git a/sormas-cargoserver/pom.xml b/sormas-cargoserver/pom.xml index b01dc9b18a5..84fb0cad9d4 100644 --- a/sormas-cargoserver/pom.xml +++ b/sormas-cargoserver/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.87.0-SNAPSHOT + 1.86.0 ../sormas-base diff --git a/sormas-ear/pom.xml b/sormas-ear/pom.xml index 2b6d48f1228..77f6a8d9788 100644 --- a/sormas-ear/pom.xml +++ b/sormas-ear/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.87.0-SNAPSHOT + 1.86.0 ../sormas-base diff --git a/sormas-keycloak-service-provider/pom.xml b/sormas-keycloak-service-provider/pom.xml index 35cf0fc8dd9..e2294a09228 100644 --- a/sormas-keycloak-service-provider/pom.xml +++ b/sormas-keycloak-service-provider/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.87.0-SNAPSHOT + 1.86.0 ../sormas-base 4.0.0 diff --git a/sormas-rest/pom.xml b/sormas-rest/pom.xml index e8c54fe44cc..4c7917edd97 100644 --- a/sormas-rest/pom.xml +++ b/sormas-rest/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.87.0-SNAPSHOT + 1.86.0 ../sormas-base diff --git a/sormas-serverlibs/pom.xml b/sormas-serverlibs/pom.xml index e803227c873..900e33ae6d5 100644 --- a/sormas-serverlibs/pom.xml +++ b/sormas-serverlibs/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.87.0-SNAPSHOT + 1.86.0 ../sormas-base 4.0.0 diff --git a/sormas-ui/pom.xml b/sormas-ui/pom.xml index 9bdf3c48466..b818499f3d5 100644 --- a/sormas-ui/pom.xml +++ b/sormas-ui/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.87.0-SNAPSHOT + 1.86.0 ../sormas-base 4.0.0 diff --git a/sormas-widgetset/pom.xml b/sormas-widgetset/pom.xml index 2e65f34fbde..97772736705 100644 --- a/sormas-widgetset/pom.xml +++ b/sormas-widgetset/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.87.0-SNAPSHOT + 1.86.0 ../sormas-base 4.0.0 From 6e4df2b7d2b31c87f278a09863e587069f6fa3c5 Mon Sep 17 00:00:00 2001 From: jenkins Date: Mon, 10 Jul 2023 12:32:16 +0200 Subject: [PATCH 010/174] [GITFLOW]Updating develop poms back to pre merge state --- sormas-api/pom.xml | 2 +- sormas-app/pom.xml | 2 +- sormas-backend/pom.xml | 2 +- sormas-base/pom.xml | 2 +- sormas-cargoserver/pom.xml | 2 +- sormas-ear/pom.xml | 2 +- sormas-keycloak-service-provider/pom.xml | 2 +- sormas-rest/pom.xml | 2 +- sormas-serverlibs/pom.xml | 2 +- sormas-ui/pom.xml | 2 +- sormas-widgetset/pom.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/sormas-api/pom.xml b/sormas-api/pom.xml index 89b8368cc31..eb1b1b89a83 100644 --- a/sormas-api/pom.xml +++ b/sormas-api/pom.xml @@ -2,7 +2,7 @@ de.symeda.sormas sormas-base - 1.86.0 + 1.87.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-app/pom.xml b/sormas-app/pom.xml index be59506bd8d..f0b488d93bb 100644 --- a/sormas-app/pom.xml +++ b/sormas-app/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.86.0 + 1.87.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-backend/pom.xml b/sormas-backend/pom.xml index b69378095e9..999e5717002 100644 --- a/sormas-backend/pom.xml +++ b/sormas-backend/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.86.0 + 1.87.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index a480f1137fb..def4aff04f5 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -5,7 +5,7 @@ de.symeda.sormas sormas-base pom - 1.86.0 + 1.87.0-SNAPSHOT 3.6.3 diff --git a/sormas-cargoserver/pom.xml b/sormas-cargoserver/pom.xml index 84fb0cad9d4..b01dc9b18a5 100644 --- a/sormas-cargoserver/pom.xml +++ b/sormas-cargoserver/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.86.0 + 1.87.0-SNAPSHOT ../sormas-base diff --git a/sormas-ear/pom.xml b/sormas-ear/pom.xml index 77f6a8d9788..2b6d48f1228 100644 --- a/sormas-ear/pom.xml +++ b/sormas-ear/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.86.0 + 1.87.0-SNAPSHOT ../sormas-base diff --git a/sormas-keycloak-service-provider/pom.xml b/sormas-keycloak-service-provider/pom.xml index e2294a09228..35cf0fc8dd9 100644 --- a/sormas-keycloak-service-provider/pom.xml +++ b/sormas-keycloak-service-provider/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.86.0 + 1.87.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-rest/pom.xml b/sormas-rest/pom.xml index 4c7917edd97..e8c54fe44cc 100644 --- a/sormas-rest/pom.xml +++ b/sormas-rest/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.86.0 + 1.87.0-SNAPSHOT ../sormas-base diff --git a/sormas-serverlibs/pom.xml b/sormas-serverlibs/pom.xml index 900e33ae6d5..e803227c873 100644 --- a/sormas-serverlibs/pom.xml +++ b/sormas-serverlibs/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.86.0 + 1.87.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-ui/pom.xml b/sormas-ui/pom.xml index b818499f3d5..9bdf3c48466 100644 --- a/sormas-ui/pom.xml +++ b/sormas-ui/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.86.0 + 1.87.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-widgetset/pom.xml b/sormas-widgetset/pom.xml index 97772736705..2e65f34fbde 100644 --- a/sormas-widgetset/pom.xml +++ b/sormas-widgetset/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.86.0 + 1.87.0-SNAPSHOT ../sormas-base 4.0.0 From 60bb0ad6226d0ad2ed9ae57272b47b36b6e3e607 Mon Sep 17 00:00:00 2001 From: sormas-vitagroup Date: Mon, 10 Jul 2023 10:46:55 +0000 Subject: [PATCH 011/174] [GitHub Actions] Update openAPI spec files --- sormas-rest/swagger.json | 2 +- sormas-rest/swagger.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sormas-rest/swagger.json b/sormas-rest/swagger.json index 6d37b8670e9..6a68d4d93a8 100644 --- a/sormas-rest/swagger.json +++ b/sormas-rest/swagger.json @@ -7,7 +7,7 @@ "url" : "https://www.gnu.org/licenses/gpl-3.0.html" }, "title" : "SORMAS REST API", - "version" : "1.86.0-SNAPSHOT" + "version" : "1.87.0-SNAPSHOT" }, "servers" : [ { "url" : "/sormas-rest" diff --git a/sormas-rest/swagger.yaml b/sormas-rest/swagger.yaml index 58131f677a0..1a3718edc6d 100644 --- a/sormas-rest/swagger.yaml +++ b/sormas-rest/swagger.yaml @@ -10,7 +10,7 @@ info: name: GPL v3 url: https://www.gnu.org/licenses/gpl-3.0.html title: SORMAS REST API - version: 1.86.0-SNAPSHOT + version: 1.87.0-SNAPSHOT servers: - url: /sormas-rest paths: From 7610c969b9009dbe588648c392a462bbd0b2bbe2 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Mon, 10 Jul 2023 13:19:00 +0200 Subject: [PATCH 012/174] qu-auto/SORQA-979 Demis - Process a Lab message that has multiple samples. Futher steps have been added. --- .../messages/MessagesDirectoryPage.java | 1 + .../e2etests/steps/api/demisSteps/DemisSteps.java | 14 ++++++++++++++ .../resources/features/sanity/web/DemisWeb.feature | 2 ++ 3 files changed, 17 insertions(+) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java index 02ca6854b92..d5ad5737672 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java @@ -138,4 +138,5 @@ public static By getProcessStatusByIndex(int index) { By.xpath("(//input[contains(@id, 'labDetails')])[2]"); public static final By NEW_SAMPLE_FORM_SECOND_PATHOGEN_LABORATORY_NAME = By.xpath("(//input[contains(@id, 'labDetails')])[3]"); + public static final By MULTIPLE_SAMPLES_HEADER = By.xpath("//div[@class= 'v-window-header'][text()='Mehrere Proben']"); } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java index f6b55ef63fc..376c51baa66 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java @@ -75,6 +75,7 @@ import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGE_POPUP_HEADER; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGE_TIME_FROM_COMBOBOX; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGE_UUID_TEXT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MULTIPLE_SAMPLES_HEADER; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_CASE_FORM_DISEASE_VARIANT_INPUT; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_FIRST_PATHOGEN_DISEASE_VARIANT_INPUT; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_FIRST_PATHOGEN_LABORATORY_NAME; @@ -910,6 +911,19 @@ public DemisSteps( demisApiService.sendLabRequest(json, loginToken), "Failed to send laboratory request"); }); + + Then( + "^I check that multiple samples window pops up$", + () -> { + webDriverHelpers.waitUntilIdentifiedElementIsPresent(MULTIPLE_SAMPLES_HEADER); + }); + + And( + "^I confirm multiple samples window$", + () -> { + webDriverHelpers.waitUntilIdentifiedElementIsPresent(POPUP_CONFIRM_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(POPUP_CONFIRM_BUTTON); + }); } private List> getTableRowsData() { diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index cecd4a5555e..ce122444856 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -500,6 +500,8 @@ Scenario: Create and send laboratory request via Demis And I check that create new case form with pathogen detection reporting process is displayed for DE And I fill only mandatory fields to convert laboratory message into a case for DE And I click on save button in the case popup + Then I check that multiple samples window pops up + And I confirm multiple samples window Then I check that new sample form with pathogen detection reporting process is displayed And I click on save sample button And I click on save sample button From 8f165cea63f5c5606cc948a1a1fdabea5847704e Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Mon, 10 Jul 2023 13:25:00 +0200 Subject: [PATCH 013/174] qu-auto/SORQA-979 Demis - Process a Lab message that has multiple samples. Multiple samples template json file have been added. --- .../labNotificationMultipleSamples.json | 705 ++++++++++++++++++ 1 file changed, 705 insertions(+) create mode 100644 sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationMultipleSamples.json diff --git a/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationMultipleSamples.json b/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationMultipleSamples.json new file mode 100644 index 00000000000..7f84cc4faf1 --- /dev/null +++ b/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationMultipleSamples.json @@ -0,0 +1,705 @@ +{ + "resourceType": "Bundle", + "id": "NotificationBundleLaboratory-example", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotificationBundleLaboratory" + ] + }, + "identifier": { + "system": "https://demis.rki.de/fhir/NamingSystem/NotificationBundleId", + "value": "0de84a15-3f79-439a-a33c-a5989927cf7d" + }, + "type": "document", + "timestamp": "2020-10-05T07:37:44.979+02:00", + "entry": [ + { + "fullUrl": "https://demis.rki.de/fhir/Composition/a194b5c3-a3c5-4ceb-9087-d7fd87e1ec4e", + "resource": { + "resourceType": "Composition", + "id": "a194b5c3-a3c5-4ceb-9087-d7fd87e1ec4e", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotificationLaboratory" + ] + }, + "identifier": { + "system": "https://demis.rki.de/fhir/NamingSystem/NotificationId", + "value": "" + }, + "status": "final", + "type": { + "coding": [ + { + "system": "http://loinc.org", + "code": "34782-3", + "display": "Infectious disease Note" + } + ] + }, + "category": [ + { + "coding": [ + { + "system": "http://loinc.org", + "code": "11502-2", + "display": "Laboratory report" + } + ] + } + ], + "subject": { + "reference": "Patient/61ebe359-bfdc-4613-8bf2-c5e300945f0n17" + }, + "date": "2020-09-16", + "author": [ + { + "reference": "PractitionerRole/61ebe359-bfdc-4613-8bf2-c5e300945f0n18" + } + ], + "title": "SARS-CoV-2-Erregernachweismeldung", + "relatesTo": [ + { + "code": "appends", + "targetReference": { + "type": "Composition", + "identifier": { + "system": "https://demis.rki.de/fhir/NamingSystem/NotificationId", + "value": "" + } + } + } + ], + "section": [ + { + "code": { + "coding": [ + { + "system": "http://loinc.org", + "code": "11502-2", + "display": "Laboratory report" + } + ] + }, + "entry": [ + { + "reference": "DiagnosticReport/61ebe359-bfdc-4613-8bf2-c5e300945f0n19" + } + ] + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/PractitionerRole/61ebe359-bfdc-4613-8bf2-c5e300945f0n18", + "resource": { + "resourceType": "PractitionerRole", + "id": "61ebe359-bfdc-4613-8bf2-c5e300945f0n18", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotifierRole" + ] + }, + "organization": { + "reference": "Organization/f812c7ab-f9d7-4dfd-81eb-71b2408f1c55" + } + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Organization/f812c7ab-f9d7-4dfd-81eb-71b2408f1c55", + "resource": { + "resourceType": "Organization", + "id": "f812c7ab-f9d7-4dfd-81eb-71b2408f1c55", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotifierFacility" + ] + }, + "identifier": [ + { + "system": "https://fhir.kbv.de/NamingSystem/KBV_NS_Base_BSNR", + "value": "123456789" + } + ], + "type": [ + { + "coding": [ + { + "system": "https://demis.rki.de/fhir/CodeSystem/organizationType", + "code": "laboratory", + "display": "Erregerdiagnostische Untersuchungsstelle" + } + ] + } + ], + "name": "Organization for Laboratory tests", + "telecom": [ + { + "system": "phone", + "value": "+49 30 09876543 221", + "use": "work" + }, + { + "system": "fax", + "value": "+49 30 09876543 99221", + "use": "work" + }, + { + "system": "email", + "value": "ifsg@demis-labortest.de", + "use": "work" + }, + { + "system": "url", + "value": "https://www.demis-labortest.de", + "use": "work" + } + ], + "address": [ + { + "line": [ + "Teststraße 123a Dritter Hinterhof" + ], + "city": "Teststadt", + "postalCode": "10115", + "country": "20422" + } + ], + "contact": [ + { + "name": { + "use": "official", + "family": "NachnameAnsprechpartnerIn", + "given": [ + "VornameAnsprechpartnerIn" + ] + } + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Patient/61ebe359-bfdc-4613-8bf2-c5e300945f0n17", + "resource": { + "resourceType": "Patient", + "id": "61ebe359-bfdc-4613-8bf2-c5e300945f0n17", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotifiedPerson" + ] + }, + "deceasedBoolean": "true", + "deceasedDateTime": "2021-07-29", + "name": [ + { + "use": "official", + "family": "", + "given": [ + "" + ] + } + ], + "telecom": [ + { + "extension": [ + { + "url": "https://demis.rki.de/fhir/StructureDefinition/Comment", + "valueString": "Ab 14 Uhr" + } + ], + "system": "phone", + "value": "+49 (0)12345 - 123456", + "use": "work" + } + ], + "gender": "female", + "birthDate": "1974-12-25", + "address": [ + { + "extension": [ + { + "url": "https://demis.rki.de/fhir/StructureDefinition/AddressUse", + "valueCoding": { + "system": "https://demis.rki.de/fhir/CodeSystem/addressUse", + "code": "ordinary" + } + }, + { + "url": "https://demis.rki.de/fhir/StructureDefinition/FacilityAddressNotifiedPerson", + "valueReference": { + "reference": "Organization/98cda07d-1fa7-47f6-ad79-e66de48d6078" + } + } + ] + } + ], + "contact": [ + { + "relationship": [ + { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v2-0131", + "code": "E" + } + ] + } + ], + "name": { + "use": "official", + "family": "", + "given": [ + "" + ] + } + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/DiagnosticReport/61ebe359-bfdc-4613-8bf2-c5e300945f0n19", + "resource": { + "resourceType": "DiagnosticReport", + "id": "61ebe359-bfdc-4613-8bf2-c5e300945f0n19", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/LaboratoryReportCVDP" + ] + }, + "basedOn": [ + { + "type": "ServiceRequest", + "identifier": { + "system": "https://demis.rki.de/fhir/NamingSystem/ServiceRequestId", + "value": "2022-0003456" + } + } + ], + "status": "final", + "code": { + "coding": [ + { + "system": "https://demis.rki.de/fhir/CodeSystem/notificationCategory", + "code": "cvdp", + "display": "Severe-Acute-Respiratory-Syndrome-Coronavirus-2 (SARS-CoV-2)" + } + ] + }, + "subject": { + "reference": "Patient/61ebe359-bfdc-4613-8bf2-c5e300945f0n17" + }, + "issued": "2021-03-04T11:45:33+11:00", + "result": [ + { + "reference": "Observation/" + } + ], + "conclusionCode": [ + { + "coding": [ + { + "system": "https://demis.rki.de/fhir/CodeSystem/conclusionCode", + "code": "pathogenDetected" + } + ] + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Organization/98cda07d-1fa7-47f6-ad79-e66de48d6078", + "resource": { + "resourceType": "Organization", + "id": "98cda07d-1fa7-47f6-ad79-e66de48d6078", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotifiedPersonFacility" + ] + }, + "type": [ + { + "coding": [ + { + "system": "https://demis.rki.de/fhir/CodeSystem/organizationType", + "code": "hospital" + } + ] + } + ], + "name": "Krankenhaus am See", + "telecom": [ + { + "system": "phone", + "value": "+49 (0)12345 - 123456", + "use": "work" + } + ], + "address": [ + { + "line": [ + "Kurzer Weg 15" + ], + "city": "Berlin", + "postalCode": "", + "country": "20422" + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Observation/", + "resource": { + "resourceType": "Observation", + "id": "", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/PathogenDetectionCVDP" + ] + }, + "identifier": { + "system": "https://demis.rki.de/fhir/NamingSystem/PathogenDetection", + "value": "externalID-abcd123" + }, + "status": "final", + "category": [ + { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/observation-category", + "code": "laboratory" + } + ] + } + ], + "code": { + "coding": [ + { + "system": "http://loinc.org", + "code": "94764-8", + "display": "SARS-CoV-2 (COVID-19) variant Sequencing Nom (Specimen)" + } + ] + }, + "subject": { + "reference": "Patient/61ebe359-bfdc-4613-8bf2-c5e300945f0n17" + }, + "valueString": "#AY.4", + "interpretation": [ + { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation", + "code": "POS" + } + ] + } + ], + "note": [ + { + "text": "Ich bin ein optionaler beschreibender Text ..." + } + ], + "method": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "115418004", + "display": "Viral Sequencing (procedure)" + } + ] + }, + "specimen": { + "reference": "Specimen/" + } + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Observation/", + "resource": { + "resourceType": "Observation", + "id": "", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/PathogenDetectionCVDP" + ] + }, + "identifier": { + "system": "https://demis.rki.de/fhir/NamingSystem/PathogenDetection", + "value": "externalID-abcd123" + }, + "status": "final", + "category": [ + { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/observation-category", + "code": "laboratory" + } + ] + } + ], + "code": { + "coding": [ + { + "system": "http://loinc.org", + "code": "94558-4", + "display": "SARS-CoV-2 (COVID-19) variant Sequencing Nom (Specimen)" + } + ] + }, + "subject": { + "reference": "Patient/61ebe359-bfdc-4613-8bf2-c5e300945f0n17" + }, + "valueString": "#B.1.617.2", + "interpretation": [ + { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation", + "code": "POS" + } + ] + } + ], + "note": [ + { + "text": "Ich bin ein optionaler beschreibender Text ..." + } + ], + "method": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "115418004", + "display": "Viral Sequencing (procedure)" + } + ] + }, + "specimen": { + "reference": "Specimen/" + } + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Observation/12349a4c-9093-467a-a3e8-050594afbd59", + "resource": { + "resourceType": "Observation", + "id": "12349a4c-9093-467a-a3e8-050594afbd59", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/PathogenDetectionCVDP" + ] + }, + "identifier": { + "system": "https://demis.rki.de/fhir/NamingSystem/PathogenDetection", + "value": "externalID-abcd123" + }, + "status": "final", + "category": [ + { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/observation-category", + "code": "laboratory" + } + ] + } + ], + "code": { + "coding": [ + { + "system": "http://loinc.org", + "code": "97097-0", + "display": "SARS-CoV-2 (COVID-19) variant Sequencing Nom (Specimen)" + } + ] + }, + "subject": { + "reference": "Patient/61ebe359-bfdc-4613-8bf2-c5e300945f0n17" + }, + "valueString": "#B.1.1.28.1_-_P.1", + "interpretation": [ + { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation", + "code": "POS" + } + ] + } + ], + "note": [ + { + "text": "Ich bin ein optionaler beschreibender Text ..." + } + ], + "method": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "115418004", + "display": "Viral Sequencing (procedure)" + } + ] + }, + "specimen": { + "reference": "Specimen/12341bca-9c53-4422-bb33-3621da084bf4" + } + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Specimen/47d61bca-9c53-4422-bb33-3621da084bf4", + "resource": { + "resourceType": "Specimen", + "id": "47d61bca-9c53-4422-bb33-3621da084bf4", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/SpecimenCVDP" + ] + }, + "type": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "309164002", + "display": "Upper respiratory swab sample (specimen)" + } + ] + }, + "subject": { + "reference": "Patient/61ebe359-bfdc-4613-8bf2-c5e300945f0n17" + }, + "receivedTime": "2020-09-27T22:01:38+02:00", + "collection": { + "collector": { + "reference": "PractitionerRole/xyz2f5-8384-4191-916b-10150c780453" + }, + "collectedDateTime": "2020-08-17T10:10:00Z" + }, + "processing": [ + { + "extension": [ + { + "url": "https://demis.rki.de/fhir/StructureDefinition/TransactionID", + "valueString": "IMS-DEMIS-10001-CVDP-be8131da-9024-41a4-a53c-3ce0d6f6fe37" + } + ], + "timeDateTime": "2020-08-18T08:10:00Z" + } + ], + "note": [ + { + "text": "Die Probe gehört zu einem Ausbruch." + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Specimen/12341bca-9c53-4422-bb33-3621da084bf4", + "resource": { + "resourceType": "Specimen", + "id": "12341bca-9c53-4422-bb33-3621da084bf4", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/SpecimenCVDP" + ] + }, + "type": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "309164002", + "display": "Upper respiratory swab sample (specimen)" + } + ] + }, + "subject": { + "reference": "Patient/61ebe359-bfdc-4613-8bf2-c5e300945f0n17" + }, + "receivedTime": "2020-09-27T22:01:38+02:00", + "collection": { + "collector": { + "reference": "PractitionerRole/xyz2f5-8384-4191-916b-10150c780453" + }, + "collectedDateTime": "2020-08-17T10:10:00Z" + }, + "processing": [ + { + "extension": [ + { + "url": "https://demis.rki.de/fhir/StructureDefinition/TransactionID", + "valueString": "IMS-DEMIS-10001-CVDP-be8131da-9024-41a4-a53c-3ce0d6f6fe37" + } + ], + "timeDateTime": "2020-08-18T08:10:00Z" + } + ], + "note": [ + { + "text": "Die Probe gehört zu einem Ausbruch." + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/PractitionerRole/xyz2f5-8384-4191-916b-10150c780453", + "resource": { + "resourceType": "PractitionerRole", + "id": "xyz2f5-8384-4191-916b-10150c780453", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/SubmittingRole" + ] + }, + "practitioner": { + "reference": "Practitioner/42cdf5-8384-4191-916b-10150c780453" + } + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Practitioner/42cdf5-8384-4191-916b-10150c780453", + "resource": { + "resourceType": "Practitioner", + "id": "42cdf5-8384-4191-916b-10150c780453", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/SubmittingPerson" + ] + }, + "name": [ + { + "use": "official", + "family": "Mantle", + "given": [ + "Karl-Heinz" + ] + } + ], + "telecom": [ + { + "system": "phone", + "value": "+49 (0)12345 - 123456", + "use": "work" + }, + { + "system": "phone", + "value": "+49 (0)12345 - 123567", + "use": "home" + } + ], + "address": [ + { + "use": "home", + "line": [ + "Erster Weg 1" + ], + "city": "Berlin", + "state": "DE-BE", + "postalCode": "10115", + "country": "20422" + } + ] + } + } + ] +} \ No newline at end of file From 9daf607709f6b724054414b72b1df43a6c998330 Mon Sep 17 00:00:00 2001 From: Michal Kozakiewicz Date: Mon, 10 Jul 2023 14:44:07 +0200 Subject: [PATCH 014/174] SORQA-1029 Stabilize "MSymptoms in case when sending from SORMAS to Meldesoftware" - created Survnet test, added Survnet buildier for SymptomService --- .../enums/JaNeinUnbekanntOptions.java | 38 ++ .../application/cases/CreateNewCasePage.java | 1 + .../entities/services/SymptomService.java | 93 +++++ .../application/cases/SymptomsTabSteps.java | 111 ++++++ .../web/application/survnet/SurvNetSteps.java | 364 +++++++++++++++++- .../features/sanity/web/Survnet.feature | 23 ++ 6 files changed, 618 insertions(+), 12 deletions(-) create mode 100644 sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/JaNeinUnbekanntOptions.java diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/JaNeinUnbekanntOptions.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/JaNeinUnbekanntOptions.java new file mode 100644 index 00000000000..5466706c8d1 --- /dev/null +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/JaNeinUnbekanntOptions.java @@ -0,0 +1,38 @@ +/* + * SORMAS® - Surveillance Outbreak Response Management & Analysis System + * Copyright © 2016-2022 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.sormas.e2etests.enums; + +import lombok.Getter; + +@Getter +public enum JaNeinUnbekanntOptions { + JA("JA"), + NEIN("NEIN"), + UNBEKANNT("UNBEKANNT"); + + private final String option; + + JaNeinUnbekanntOptions(String option) { + this.option = option; + } + + @Override + public String toString() { + return this.option; + } +} diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/CreateNewCasePage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/CreateNewCasePage.java index 3dcfc6b0328..151f1708619 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/CreateNewCasePage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/CreateNewCasePage.java @@ -141,4 +141,5 @@ public class CreateNewCasePage { By.xpath("//label[text()='W\u00E4hlen Sie eine passende Person']"); public static final By SELECT_EXISTING_CASE_DE = By.xpath("//label[text()='Einen vorhandenen Fall w\u00E4hlen']"); + public static final By CATEGORY_SAVED_POPUP = By.cssSelector(".v-Notification-caption"); } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/SymptomService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/SymptomService.java index 37aa6fd671d..90dffaad48e 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/SymptomService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/SymptomService.java @@ -19,6 +19,7 @@ package org.sormas.e2etests.entities.services; import static org.sormas.e2etests.entities.pojo.helpers.ShortUUIDGenerator.generateShortUUID; +import static org.sormas.e2etests.enums.JaNeinUnbekanntOptions.*; import static org.sormas.e2etests.enums.YesNoUnknownOptions.NO; import static org.sormas.e2etests.enums.YesNoUnknownOptions.UNKNOWN; import static org.sormas.e2etests.enums.YesNoUnknownOptions.YES; @@ -163,4 +164,96 @@ public Symptoms buildEditGeneratedSymptomsWithUnknownOptions() { .symptomsComments(generateShortUUID()) .build(); } + + @SneakyThrows + public Symptoms buildEditGeneratedSymptomsSurvnet() { + return Symptoms.builder() + .maximumBodyTemperatureInC("35,2") + .sourceOfBodyTemperature("rektal") + .fever(JA.toString()) + .shivering(JA.toString()) + .headache(JA.toString()) + .musclePain(JA.toString()) + .feelingIll(JA.toString()) + .chillsOrSweats(JA.toString()) + .acuteRespiratoryDistressSyndrome(JA.toString()) + .soreThroat(JA.toString()) + .cough(JA.toString()) + .runnyNose(JA.toString()) + .pneumoniaClinicalOrRadiologic(JA.toString()) + .respiratoryDiseaseVentilation(JA.toString()) + .oxygenSaturationLower94(JA.toString()) + .rapidBreathing(JA.toString()) + .difficultyBreathing(JA.toString()) + .fastHeartRate(JA.toString()) + .diarrhea(JA.toString()) + .nausea(JA.toString()) + .lossOfSmell(JA.toString()) + .lossOfTaste(JA.toString()) + .otherNonHemorrhagicSymptoms(JA.toString()) + .symptomsComments(generateShortUUID()) + .firstSymptom("Andere klinische Symptome") + .dateOfSymptom(LocalDate.now().minusDays(2)) + .build(); + } + + @SneakyThrows + public Symptoms buildEditGeneratedSymptomsSurvnetWithNEINOptions() { + return Symptoms.builder() + .maximumBodyTemperatureInC("35,2") + .sourceOfBodyTemperature("rektal") + .fever(NEIN.toString()) + .shivering(NEIN.toString()) + .headache(NEIN.toString()) + .musclePain(NEIN.toString()) + .feelingIll(NEIN.toString()) + .chillsOrSweats(NEIN.toString()) + .acuteRespiratoryDistressSyndrome(NEIN.toString()) + .soreThroat(NEIN.toString()) + .cough(NEIN.toString()) + .runnyNose(NEIN.toString()) + .pneumoniaClinicalOrRadiologic(NEIN.toString()) + .respiratoryDiseaseVentilation(NEIN.toString()) + .oxygenSaturationLower94(NEIN.toString()) + .rapidBreathing(NEIN.toString()) + .difficultyBreathing(NEIN.toString()) + .fastHeartRate(NEIN.toString()) + .diarrhea(NEIN.toString()) + .nausea(NEIN.toString()) + .lossOfSmell(NEIN.toString()) + .lossOfTaste(NEIN.toString()) + .otherNonHemorrhagicSymptoms(NEIN.toString()) + .symptomsComments(generateShortUUID()) + .build(); + } + + @SneakyThrows + public Symptoms buildEditGeneratedSymptomsSurvnetWithUNBEKANNTOptions() { + return Symptoms.builder() + .maximumBodyTemperatureInC("35,2") + .sourceOfBodyTemperature("rektal") + .fever(UNBEKANNT.toString()) + .shivering(UNBEKANNT.toString()) + .headache(UNBEKANNT.toString()) + .musclePain(UNBEKANNT.toString()) + .feelingIll(UNBEKANNT.toString()) + .chillsOrSweats(UNBEKANNT.toString()) + .acuteRespiratoryDistressSyndrome(UNBEKANNT.toString()) + .soreThroat(UNBEKANNT.toString()) + .cough(UNBEKANNT.toString()) + .runnyNose(UNBEKANNT.toString()) + .pneumoniaClinicalOrRadiologic(UNBEKANNT.toString()) + .respiratoryDiseaseVentilation(UNBEKANNT.toString()) + .oxygenSaturationLower94(UNBEKANNT.toString()) + .rapidBreathing(UNBEKANNT.toString()) + .difficultyBreathing(UNBEKANNT.toString()) + .fastHeartRate(UNBEKANNT.toString()) + .diarrhea(UNBEKANNT.toString()) + .nausea(UNBEKANNT.toString()) + .lossOfSmell(UNBEKANNT.toString()) + .lossOfTaste(UNBEKANNT.toString()) + .otherNonHemorrhagicSymptoms(UNBEKANNT.toString()) + .symptomsComments(generateShortUUID()) + .build(); + } } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/SymptomsTabSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/SymptomsTabSteps.java index 2618ea28c04..f954d50f457 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/SymptomsTabSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/SymptomsTabSteps.java @@ -21,6 +21,7 @@ import static org.sormas.e2etests.enums.YesNoUnknownOptions.NO; import static org.sormas.e2etests.enums.YesNoUnknownOptions.UNKNOWN; import static org.sormas.e2etests.enums.YesNoUnknownOptions.YES; +import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.CATEGORY_SAVED_POPUP; import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.SAVE_BUTTON; import static org.sormas.e2etests.pages.application.cases.EditCasePage.UUID_INPUT; import static org.sormas.e2etests.pages.application.cases.FollowUpTabPage.ABDOMINAL_PAIN_OPTIONS; @@ -204,6 +205,36 @@ public SymptomsTabSteps( } }); + When( + "I change all symptoms fields to {string} option field and save on Survnet", + (String option) -> { + switch (option) { + case "NO": + break; + case "NO_AND_OTHER_SYMPTOMS_TO_YES": + break; + case "UNKNOWN": + break; + case "JA": + symptoms = symptomService.buildEditGeneratedSymptomsSurvnet(); + FillSymptomsDataSurvnet(symptoms); + fillOtherSymptoms( + symptoms.getSymptomsComments()); // otherNonHemorrhagicSymptomsText field conected + // with selectOtherClinicalSymptoms //not mapped + selectFistSymptom(symptoms.getFirstSymptom()); // not mapped + fillOtherSymptoms(symptoms.getSymptomsComments()); //notmapped + fillSymptomsComments(symptoms.getSymptomsComments()); //not mapped + + fillDateOfSymptomDE(symptoms.getDateOfSymptom(), Locale.GERMAN); + webDriverHelpers.clickOnWebElementBySelector(SAVE_BUTTON); + + // Todo obluzenuie ponizszego capture(CATEGORY_SAVED_POPUP) + webDriverHelpers.waitUntilElementIsVisibleAndClickable(CATEGORY_SAVED_POPUP); + webDriverHelpers.clickOnWebElementBySelector(CATEGORY_SAVED_POPUP); + break; + } + }); + // TODO refactor this to be provide the checkbox and select any option not only yes And( "I check Yes Option for Soar Throat on Symptoms tab page", @@ -247,6 +278,25 @@ public SymptomsTabSteps( selectFever(option); }); + And( + "^I set \"([^\"]*)\" Symptoms to \"([^\"]*)\" on the Symptoms tab$", + (String symptom, String option) -> { + switch (symptom) { + case "Fever": + selectFever(option); + break; + case "Shivering": + selectShivering(option); + break; + } + }); + + And( + "^I collect \"([^\"]*)\" Symptoms checkbox value from the Symptoms tab", + (String option) -> { + selectFever(option); + }); + And( "^I set Date of symptom onset to (\\d+) days before the vaccination date on the Symptoms tab for DE$", (Integer numberOfDays) -> { @@ -330,6 +380,67 @@ private void FillSymptomsData(Symptoms symptoms) { selectFistSymptom(symptoms.getFirstSymptom()); } + private void FillSymptomsDataSurvnet(Symptoms symptoms) { + selectMaximumBodyTemperatureInCCombobox(symptoms.getMaximumBodyTemperatureInC()); + selectSourceOfBodyTemperature(symptoms.getSourceOfBodyTemperature()); + // selectFever(symptoms.getFever()); --ok + // selectShivering(symptoms.getShivering()); --ok + // selectHeadache(symptoms.getHeadache()); --oh + // selectMusclePain(symptoms.getMusclePain()); --ok + // selectFeelingIll(symptoms.getFeelingIll()); --ok + // selectChillsOrSweats(symptoms.getChillsOrSweats()); --ok + // selectAcuteRespiratoryDistressSyndrome(symptoms.getAcuteRespiratoryDistressSyndrome()); + // selectSoreThroat(symptoms.getSoreThroat()); --ok + // selectCough(symptoms.getCough()); --ok + // selectRunnyNose(symptoms.getRunnyNose()); --ok + // selectPneumoniaClinicalOrRadiologic(symptoms.getPneumoniaClinicalOrRadiologic()); + // selectRespiratoryDiseaseVentilation(symptoms.getRespiratoryDiseaseVentilation()); + // selectOxygenSaturationLower94(symptoms.getOxygenSaturationLower94()); --not mapped + // selectRapidBreathing(symptoms.getRapidBreathing()); --ok + // selectDifficultyBreathing(symptoms.getDifficultyBreathing()); --ok + // selectFastHeartRate(symptoms.getFastHeartRate()); --ok + // selectDiarrhea(symptoms.getDiarrhea()); --ok + // selectNausea(symptoms.getNausea()); --ok + // selectLossOfSmell(symptoms.getLossOfSmell()); --ok + // selectLossOfTaste(symptoms.getLossOfTaste()); --ok + selectOtherClinicalSymptoms(symptoms.getOtherNonHemorrhagicSymptoms()); + + // selectChillsOrSweats(symptoms.getChillsOrSweats()); + // selectHeadache(symptoms.getHeadache()); + // selectMusclePain(symptoms.getMusclePain()); + // selectAcuteRespiratoryDistressSyndrome(symptoms.getAcuteRespiratoryDistressSyndrome()); + // selectCough(symptoms.getCough()); + // selectPneumoniaClinicalOrRadiologic(symptoms.getPneumoniaClinicalOrRadiologic()); + // selectDifficultyBreathing(symptoms.getDifficultyBreathing()); + // selectRapidBreathing(symptoms.getRapidBreathing()); + // selectRunnyNose(symptoms.getRunnyNose()); + // selectSoreThroat(symptoms.getSoreThroat()); + // selectDiarrhea(symptoms.getDiarrhea()); + // selectNausea(symptoms.getNausea()); + // selectLossOfSmell(symptoms.getLossOfSmell()); + // selectLossOfTaste(symptoms.getLossOfTaste()); + // selectOtherClinicalSymptoms(symptoms.getOtherNonHemorrhagicSymptoms()); + // selectAbnormalLungXrayFindings(symptoms.getAbnormalLungXrayFindings()); + // selectFatigueWeakness(symptoms.getFatigueWeakness()); + // selectJointPain(symptoms.getJointPain()); + // selectCoughWithHeamoptysis(symptoms.getCoughWithHeamoptysis()); + // selectCoughWithSputum(symptoms.getCoughWithSputum()); + // selectFluidInLungCavityXray(symptoms.getFluidInLungCavityXray()); + // selectFluidInLungCavityAuscultation(symptoms.getFluidInLungCavityAuscultation()); + // selectInDrawingOfChestWall(symptoms.getInDrawingOfChestWall()); + // selectAbdominalPain(symptoms.getAbdominalPain()); + // selectVomiting(symptoms.getVomiting()); + // selectSkinUlcers(symptoms.getSkinUlcers()); + // selectUnexplainedBleeding(symptoms.getUnexplainedBleeding()); + // selectComa(symptoms.getComa()); + // selectLymphadenopathy(symptoms.getLymphadenopathy()); + // selectInabilityToWalk(symptoms.getInabilityToWalk()); + // selectSkinRash(symptoms.getSkinRash()); + // selectConfusedDisoriented(symptoms.getConfusedDisoriented()); + // selectSeizures(symptoms.getSeizures()); + // selectFistSymptom(symptoms.getFirstSymptom()); + } + private void FillSymptomsDataForNoUnknown(Symptoms symptoms) { selectMaximumBodyTemperatureInCCombobox(symptoms.getMaximumBodyTemperatureInC()); selectSourceOfBodyTemperature(symptoms.getSourceOfBodyTemperature()); diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java index 47315b25eec..a365b52a5e0 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java @@ -1,6 +1,18 @@ package org.sormas.e2etests.steps.web.application.survnet; +import static org.sormas.e2etests.helpers.SchemaValidator.XMLSchemaValidator.validateXMLSchema; +import static org.sormas.e2etests.helpers.comparison.XMLComparison.compareXMLFiles; +import static org.sormas.e2etests.helpers.comparison.XMLComparison.extractDiffNodes; +import static org.sormas.e2etests.pages.application.AboutPage.SORMAS_VERSION_LINK; +import static org.sormas.e2etests.steps.web.application.cases.SymptomsTabSteps.symptoms; + import cucumber.api.java8.En; +import java.time.LocalDate; +import java.time.Period; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; +import javax.inject.Inject; import lombok.extern.slf4j.Slf4j; import org.jdom2.Attribute; import org.jdom2.DataConversionException; @@ -15,18 +27,6 @@ import org.sormas.e2etests.steps.web.application.persons.EditPersonSteps; import org.testng.asserts.SoftAssert; -import javax.inject.Inject; -import java.time.LocalDate; -import java.time.Period; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.List; - -import static org.sormas.e2etests.helpers.SchemaValidator.XMLSchemaValidator.validateXMLSchema; -import static org.sormas.e2etests.helpers.comparison.XMLComparison.compareXMLFiles; -import static org.sormas.e2etests.helpers.comparison.XMLComparison.extractDiffNodes; -import static org.sormas.e2etests.pages.application.AboutPage.SORMAS_VERSION_LINK; - @Slf4j public class SurvNetSteps implements En { @@ -78,6 +78,338 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { softly.assertAll(); }); + And( + "I check if \"([^\"]*)\" SYMPTOMS in SORMAS generated single XML file is correctS", + (String symptom) -> { + // ToDO -consider to change all expecrted... to mor global expectedValue !!! + String expectedValue = null; + String symptomOption; + String symptomUI; + + switch (symptom) { + case "Fever": + // String symptomOption = getValueFromSpecificFieldByName(singleXmlFile, + // "Symptom0088"); + // String symptomUI = symptoms.getFever(); + + // if (symptomUI == "JA") expectedValue = "true"; + // else expectedValue = "false"; + + // softly.assertEquals(feverOption, expectedValue, "Fever checkbox value is + // incorrect!"); + softly.assertAll(); + break; + case "Shivering": + String expectedShivering = null; + String shiveringOption = + getValueFromSpecificFieldByName(singleXmlFile, "Symptom0101"); + String symptomShivering = symptoms.getFever(); + + if (symptomShivering == "JA") expectedShivering = "true"; + else expectedShivering = "false"; + + softly.assertEquals( + shiveringOption, expectedShivering, "Shivering checkbox value is incorrect!"); + softly.assertAll(); + break; + } + }); + + And( + "I check if \"([^\"]*)\" SYMPTOM in SORMAS generated single XML file is correct", + (String symptom) -> { + // ToDO -consider to change all expecrted... to mor global expectedValue !!! + String expectedValue = null; + switch (symptom) { + case "Fever": + String expectedFever = null; + String feverOption = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0088"); + String symptomFever = symptoms.getFever(); + + if (symptomFever == "JA") expectedFever = "true"; + else expectedFever = "false"; + + softly.assertEquals(feverOption, expectedFever, "Fever checkbox value is incorrect!"); + softly.assertAll(); + break; + case "Shivering": + String expectedShivering = null; + String shiveringOption = + getValueFromSpecificFieldByName(singleXmlFile, "Symptom0101"); + String symptomShivering = symptoms.getFever(); + + if (symptomShivering == "JA") expectedShivering = "true"; + else expectedShivering = "false"; + + softly.assertEquals( + shiveringOption, expectedShivering, "Shivering checkbox value is incorrect!"); + softly.assertAll(); + break; + case "Headache": + String expectedHeadache = null; + String headacheOption = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0101"); + String symptomHeadache = symptoms.getHeadache(); + + if (symptomHeadache == "JA") expectedHeadache = "true"; + else expectedHeadache = "false"; + + softly.assertEquals( + headacheOption, expectedHeadache, "Headache checkbox value is incorrect!"); + softly.assertAll(); + break; + case "MusclePain": + String expectedMusclePain = null; + String musclePaineOption = + getValueFromSpecificFieldByName(singleXmlFile, "Symptom0101"); + String symptomMusclePain = symptoms.getMusclePain(); + + if (symptomMusclePain == "JA") expectedMusclePain = "true"; + else expectedMusclePain = "false"; + + softly.assertEquals( + musclePaineOption, expectedMusclePain, "MusclePain checkbox value is incorrect!"); + softly.assertAll(); + break; + case "FeelingIll": + String expectedFeelingIll = null; + String feelingIllOption = + getValueFromSpecificFieldByName(singleXmlFile, "Symptom0101"); + String symptomFeelingIll = symptoms.getFeelingIll(); + + if (symptomFeelingIll == "JA") expectedFeelingIll = "true"; + else expectedFeelingIll = "false"; + + softly.assertEquals( + feelingIllOption, expectedFeelingIll, "FeelingIll checkbox value is incorrect!"); + softly.assertAll(); + break; + case "ChillsSweats": + System.out.print("Not mapped to xml !!!"); + break; + case "AcuteRespiratoryDistressSyndrome": + String expectedAcuteRespiratoryDistressSyndrome = null; + String acuteRespiratoryDistressSyndromeOption = + getValueFromSpecificFieldByName(singleXmlFile, "Symptom0394"); + String symptomAcuteRespiratoryDistressSyndrome = + symptoms.getAcuteRespiratoryDistressSyndrome(); + + if (symptomAcuteRespiratoryDistressSyndrome == "JA") + expectedAcuteRespiratoryDistressSyndrome = "true"; + else expectedAcuteRespiratoryDistressSyndrome = "false"; + + softly.assertEquals( + acuteRespiratoryDistressSyndromeOption, + expectedAcuteRespiratoryDistressSyndrome, + "AcuteRespiratoryDistressSyndrome checkbox value is incorrect!"); + softly.assertAll(); + break; + case "SoreThroat": + String expectedSoreThroat = null; + String soreThroatOption = + getValueFromSpecificFieldByName(singleXmlFile, "Symptom0103"); + String symptomSoreThroat = symptoms.getSoreThroat(); + + if (symptomSoreThroat == "JA") expectedSoreThroat = "true"; + else expectedSoreThroat = "false"; + + softly.assertEquals( + soreThroatOption, expectedSoreThroat, "SoreThroat checkbox value is incorrect!"); + softly.assertAll(); + break; + case "Cough": + String expectedCough = null; + String coughOption = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0130"); + String symptomCought = symptoms.getCough(); + + if (symptomCought == "JA") expectedCough = "true"; + else expectedCough = "false"; + + softly.assertEquals(coughOption, expectedCough, "Cough checkbox value is incorrect!"); + softly.assertAll(); + break; + case "RunnyNose": + String expectedRunnyNose = null; + String runnyNoseOption = + getValueFromSpecificFieldByName(singleXmlFile, "Symptom0225"); + String symptomRunnyNose = symptoms.getRunnyNose(); + + if (symptomRunnyNose == "JA") expectedRunnyNose = "true"; + else expectedRunnyNose = "false"; + + softly.assertEquals( + runnyNoseOption, expectedRunnyNose, "RunnyNose checkbox value is incorrect!"); + softly.assertAll(); + break; + case "PneumoniaClinicalOrRadiologic": + String expectedPneumoniaClinicalOrRadiologic = null; + String pneumoniaClinicalOrRadiologicOption = + getValueFromSpecificFieldByName(singleXmlFile, "Symptom0158"); + String symptomPneumoniaClinicalOrRadiologic = + symptoms.getPneumoniaClinicalOrRadiologic(); + + if (symptomPneumoniaClinicalOrRadiologic == "JA") + expectedPneumoniaClinicalOrRadiologic = "true"; + else expectedPneumoniaClinicalOrRadiologic = "false"; + + softly.assertEquals( + pneumoniaClinicalOrRadiologicOption, + expectedPneumoniaClinicalOrRadiologic, + "PneumoniaClinicalOrRadiologic checkbox value is incorrect!"); + softly.assertAll(); + break; + case "RespiratoryDiseaseVentilation": + String expectedRespiratoryDiseaseVentilation = null; + String respiratoryDiseaseVentilationOption = + getValueFromSpecificFieldByName(singleXmlFile, "Symptom0393"); + String symptomRespiratoryDiseaseVentilation = + symptoms.getRespiratoryDiseaseVentilation(); + + if (symptomRespiratoryDiseaseVentilation == "JA") + expectedRespiratoryDiseaseVentilation = "true"; + else expectedRespiratoryDiseaseVentilation = "false"; + + softly.assertEquals( + respiratoryDiseaseVentilationOption, + expectedRespiratoryDiseaseVentilation, + "RespiratoryDiseaseVentilation checkbox value is incorrect!"); + softly.assertAll(); + break; + case "oxygenSaturationLower94": + System.out.print("Not mapped to xml !!!"); + break; + case "RapidBreathing": + String expectedRapidBreathing = null; + String rapidBreathingOption = + getValueFromSpecificFieldByName(singleXmlFile, "Symptom0418"); + String symptomRapidBreathing = symptoms.getRapidBreathing(); + + if (symptomRapidBreathing == "JA") expectedRapidBreathing = "true"; + else expectedRapidBreathing = "false"; + + softly.assertEquals( + rapidBreathingOption, + expectedRapidBreathing, + "RapidBreathing checkbox value is incorrect!"); + softly.assertAll(); + break; + case "DifficultyBreathing": + String expecteDdifficultyBreathing = null; + String difficultyBreathingOption = + getValueFromSpecificFieldByName(singleXmlFile, "Symptom0064"); + String symptomDifficultyBreathing = symptoms.getDifficultyBreathing(); + + if (symptomDifficultyBreathing == "JA") expecteDdifficultyBreathing = "true"; + else expecteDdifficultyBreathing = "false"; + + softly.assertEquals( + difficultyBreathingOption, + expecteDdifficultyBreathing, + "RapidBreathing checkbox value is incorrect!"); + softly.assertAll(); + break; + case "FastHeartRate": + String expectedFastHeartRate = null; + String fastHeartRateOption = + getValueFromSpecificFieldByName(singleXmlFile, "Symptom0245"); + String symptomFastHeartRate = symptoms.getFastHeartRate(); + + if (symptomFastHeartRate == "JA") expectedFastHeartRate = "true"; + else expectedFastHeartRate = "false"; + + softly.assertEquals( + fastHeartRateOption, + expectedFastHeartRate, + "FastHeartRate checkbox value is incorrect!"); + softly.assertAll(); + break; + case "Diarrhea": + String expectedDiarrhea = null; + String diarrheaOption = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0062"); + String symptomDiarrhea = symptoms.getDiarrhea(); + + if (symptomDiarrhea == "JA") expectedDiarrhea = "true"; + else expectedDiarrhea = "false"; + + softly.assertEquals( + diarrheaOption, expectedDiarrhea, "Diarrhea checkbox value is incorrect!"); + softly.assertAll(); + break; + case "Nausea": + String expectedNausea = null; + String nauseaOption = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0101"); + String symptomNausea = symptoms.getNausea(); + + if (symptomNausea == "JA") expectedNausea = "true"; + else expectedNausea = "false"; + + softly.assertEquals( + nauseaOption, expectedNausea, symptom + " checkbox value is incorrect!"); + softly.assertAll(); + break; + case "LossOfSmell": + String expectedLossOfSmell = null; + String lossOfSmellOption = + getValueFromSpecificFieldByName(singleXmlFile, "Symptom0416"); + String symptomLossOfSmell = symptoms.getLossOfSmell(); + + if (symptomLossOfSmell == "JA") expectedLossOfSmell = "true"; + else expectedLossOfSmell = "false"; + + softly.assertEquals( + lossOfSmellOption, + expectedLossOfSmell, + symptom + " checkbox value is incorrect!"); + softly.assertAll(); + break; + case "LossOfTaste": + String expectedLossOfTaste = null; + String lossOfTasteOption = + getValueFromSpecificFieldByName(singleXmlFile, "Symptom0417"); + String symptomLossOfTaste = symptoms.getLossOfTaste(); + + if (symptomLossOfTaste == "JA") expectedLossOfTaste = "true"; + else expectedLossOfTaste = "false"; + + softly.assertEquals( + lossOfTasteOption, + expectedLossOfTaste, + symptom + " checkbox value is incorrect!"); + softly.assertAll(); + break; + case "OtherNonHemorrhagicSymptoms": + String expectedOtherNonHemorrhagicSymptoms = null; + String otherNonHemorrhagicSymptomsOption = + getValueFromSpecificFieldByName(singleXmlFile, "Symptom0101"); + String symptomOtherNonHemorrhagicSymptoms = symptoms.getOtherNonHemorrhagicSymptoms(); + + if (symptomOtherNonHemorrhagicSymptoms == "JA") + expectedOtherNonHemorrhagicSymptoms = "true"; + else expectedOtherNonHemorrhagicSymptoms = "false"; + + softly.assertEquals( + otherNonHemorrhagicSymptomsOption, + expectedOtherNonHemorrhagicSymptoms, + symptom + " checkbox value is incorrect!"); + softly.assertAll(); + break; + case "otherNonHemorrhagicSymptomsText": // mandatory comment field for + // OtherNonHemorrhagicSymptoms!!! + System.out.print("Not mapped to xml !!!"); + break; + case "OnsetOfDisease": + String onsetOfDiseaseOptionDate = + getValueFromSpecificFieldByName(singleXmlFile, "OnsetOfDisease").substring(0, 10); + String expectedOnsetOfDiseaseDate = symptoms.getDateOfSymptom().toString(); + + softly.assertEquals( + onsetOfDiseaseOptionDate, + expectedOnsetOfDiseaseDate, + symptom + " date value is incorrect!"); + softly.assertAll(); + break; + } + }); + And( "I check if sex for all {int} cases in SORMAS generated bulk XML file is correct", (Integer caseNumber) -> { @@ -175,6 +507,14 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { + ".xml"); }); + And( + "^I open locally SORMAS generated XML file for single message$", + () -> { + singleXmlFile = + XMLParser.getDocument( + "C:\\Sormas\\SORMAS-Project\\sormas-e2e-tests\\src\\main\\resources\\survnetXMLTemplates\\FeverShivering.xml"); + }); + And( "^I open SORMAS generated XML file for bulk message$", () -> { diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature index 35624cdaa8c..539d9b64e44 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature @@ -89,6 +89,29 @@ Feature: Survnet tests And I check if external person uuid for all 2 cases in SORMAS generated bult XML file is correct And I check if "date of report" for all 2 cases in SORMAS generated bulk XML file is correct + @tmsLink=SORQA-1029 + Scenario: Symptoms in case when sending from SORMAS to Meldesoftware + Given I log in as a Survnet + When I click on the Cases button from navbar + And I click on the NEW CASE button + + And I open locally SORMAS generated XML file for single message + + And I create a new case with mandatory data only for Survnet DE + And I navigate to symptoms tab + Then I change all symptoms fields to "JA" option field and save on Survnet + # And I set "Fever" Symptoms to "JA" on the Symptoms tab + # And I set "Shivering" Symptoms to "JA" on the Symptoms tab + # And I save the Symptoms data + And I navigate to case tab + And I click on Send to reporting tool button on Edit Case page + And I collect case external UUID from Edit Case page + Then I wait 50 seconds for system reaction + # Then I open SORMAS generated XML file for single message + And I check if "OnsetOfDisease" SYMPTOM in SORMAS generated single XML file is correct + + + @tmsLink=SORQA-1027 Scenario: Calculated age in case when sending from SORMAS to Meldesoftware Given I log in as a Survnet From 65582835c7f9cfdd30c6e6a8344b34f8f11d3578 Mon Sep 17 00:00:00 2001 From: Stefan Kock Date: Mon, 10 Jul 2023 15:59:25 +0200 Subject: [PATCH 015/174] #12242 Dependency updates io.grpc ........................ 1.50.0 -> 1.56.1 io.netty ....................... 4.1.79 -> 4.1.94 io.netty:netty-tcnative-boringssl-static .......... 2.0.54 -> 2.0.61 - Listed the dependencies for direct version control --- sormas-base/pom.xml | 59 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index def4aff04f5..fab4bd4aa3d 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -35,7 +35,9 @@ ${vaadin.version} 2.2.12 1.70 + 1.56.1 21.0.1 + 4.1.94.Final 5.0.7.Final 1.8.22 2.0.4 @@ -533,6 +535,63 @@ provided + + io.grpc + grpc-context + ${grpc.version} + provided + + + io.grpc + grpc-netty + ${grpc.version} + provided + + + io.grpc + grpc-protobuf + ${grpc.version} + provided + + + io.grpc + grpc-stub + ${grpc.version} + provided + + + + io.netty + netty-codec-http2 + ${netty.version} + provided + + + io.netty + netty-handler-proxy + ${netty.version} + provided + + + io.netty + netty-transport-native-epoll + ${netty.version} + provided + linux-x86_64 + + + io.netty + netty-transport-native-unix-common + ${netty.version} + provided + + + io.netty + netty-tcnative-boringssl-static + 2.0.61.Final + provided + + io.swagger.core.v3 swagger-jaxrs2 From 78c9f74479da78185e4da79dc3ca0f7c78e37530 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jul 2023 17:47:41 +0000 Subject: [PATCH 016/174] Bump swagger.version from 2.2.12 to 2.2.15 in /sormas-base Bumps `swagger.version` from 2.2.12 to 2.2.15. Updates `swagger-jaxrs2` from 2.2.12 to 2.2.15 Updates `swagger-jaxrs2-servlet-initializer-v2` from 2.2.12 to 2.2.15 Updates `swagger-maven-plugin` from 2.2.12 to 2.2.15 --- updated-dependencies: - dependency-name: io.swagger.core.v3:swagger-jaxrs2 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.swagger.core.v3:swagger-jaxrs2-servlet-initializer-v2 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.swagger.core.v3:swagger-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index def4aff04f5..18c73d5e60f 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -33,7 +33,7 @@ TODO: Remove bootstrap.js in widgetset 8.14.3 ${vaadin.version} - 2.2.12 + 2.2.15 1.70 21.0.1 5.0.7.Final From a6044288eaa107f231d9bb93edd88edab0706302 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Tue, 11 Jul 2023 11:13:28 +0200 Subject: [PATCH 017/174] qu-auto/SORQA-979 Demis - Process a Lab message that has multiple samples. Multiple samples template json file have been edited. --- .../labNotificationMultipleSamples.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationMultipleSamples.json b/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationMultipleSamples.json index 7f84cc4faf1..bf7bc1c469c 100644 --- a/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationMultipleSamples.json +++ b/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationMultipleSamples.json @@ -481,10 +481,10 @@ } }, { - "fullUrl": "https://demis.rki.de/fhir/Observation/12349a4c-9093-467a-a3e8-050594afbd59", + "fullUrl": "https://demis.rki.de/fhir/Observation/", "resource": { "resourceType": "Observation", - "id": "12349a4c-9093-467a-a3e8-050594afbd59", + "id": "", "meta": { "profile": [ "https://demis.rki.de/fhir/StructureDefinition/PathogenDetectionCVDP" @@ -543,15 +543,15 @@ ] }, "specimen": { - "reference": "Specimen/12341bca-9c53-4422-bb33-3621da084bf4" + "reference": "Specimen/" } } }, { - "fullUrl": "https://demis.rki.de/fhir/Specimen/47d61bca-9c53-4422-bb33-3621da084bf4", + "fullUrl": "https://demis.rki.de/fhir/Specimen/", "resource": { "resourceType": "Specimen", - "id": "47d61bca-9c53-4422-bb33-3621da084bf4", + "id": "", "meta": { "profile": [ "https://demis.rki.de/fhir/StructureDefinition/SpecimenCVDP" @@ -595,10 +595,10 @@ } }, { - "fullUrl": "https://demis.rki.de/fhir/Specimen/12341bca-9c53-4422-bb33-3621da084bf4", + "fullUrl": "https://demis.rki.de/fhir/Specimen/", "resource": { "resourceType": "Specimen", - "id": "12341bca-9c53-4422-bb33-3621da084bf4", + "id": "", "meta": { "profile": [ "https://demis.rki.de/fhir/StructureDefinition/SpecimenCVDP" From eadfcad05ee70dac7fd49a320ca75b2715a60fb0 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Tue, 11 Jul 2023 11:25:46 +0200 Subject: [PATCH 018/174] qu-auto/SORQA-979 Demis - Process a Lab message that has multiple samples. Multiple samples template json file have been edited. --- .../demisJsonTemplates/labNotificationMultipleSamples.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationMultipleSamples.json b/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationMultipleSamples.json index bf7bc1c469c..2c278c2c83d 100644 --- a/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationMultipleSamples.json +++ b/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationMultipleSamples.json @@ -695,7 +695,7 @@ ], "city": "Berlin", "state": "DE-BE", - "postalCode": "10115", + "postalCode": "", "country": "20422" } ] From 228c01da78a94b26c99e904b41f02ce48a247b03 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Tue, 11 Jul 2023 11:52:36 +0200 Subject: [PATCH 019/174] qu-auto/SORQA-979 Demis - Process a Lab message that has multiple samples. Multiple samples template json file have been edited. --- .../demisJsonTemplates/labNotificationMultipleSamples.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationMultipleSamples.json b/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationMultipleSamples.json index 2c278c2c83d..220ea696dbb 100644 --- a/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationMultipleSamples.json +++ b/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationMultipleSamples.json @@ -548,10 +548,10 @@ } }, { - "fullUrl": "https://demis.rki.de/fhir/Specimen/", + "fullUrl": "https://demis.rki.de/fhir/Specimen/", "resource": { "resourceType": "Specimen", - "id": "", + "id": "", "meta": { "profile": [ "https://demis.rki.de/fhir/StructureDefinition/SpecimenCVDP" From f6468600e16e5edd9092d32249dc8da32c4499fd Mon Sep 17 00:00:00 2001 From: Michal Kozakiewicz Date: Tue, 11 Jul 2023 11:57:52 +0200 Subject: [PATCH 020/174] SORQA-1029 Stabilize "Symptoms in case when sending from SORMAS to Meldesoftware" - added tests for No and Unknowc options, code refactoring --- ...ptions.java => YesNoUnknownOptionsDE.java} | 4 +- .../entities/services/SymptomService.java | 108 +++--- .../application/cases/SymptomsTabSteps.java | 133 ++----- .../web/application/survnet/SurvNetSteps.java | 352 ++++++++---------- .../features/sanity/web/Survnet.feature | 103 ++++- 5 files changed, 336 insertions(+), 364 deletions(-) rename sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/{JaNeinUnbekanntOptions.java => YesNoUnknownOptionsDE.java} (93%) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/JaNeinUnbekanntOptions.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/YesNoUnknownOptionsDE.java similarity index 93% rename from sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/JaNeinUnbekanntOptions.java rename to sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/YesNoUnknownOptionsDE.java index 5466706c8d1..127c93baae4 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/JaNeinUnbekanntOptions.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/YesNoUnknownOptionsDE.java @@ -20,14 +20,14 @@ import lombok.Getter; @Getter -public enum JaNeinUnbekanntOptions { +public enum YesNoUnknownOptionsDE { JA("JA"), NEIN("NEIN"), UNBEKANNT("UNBEKANNT"); private final String option; - JaNeinUnbekanntOptions(String option) { + YesNoUnknownOptionsDE(String option) { this.option = option; } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/SymptomService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/SymptomService.java index 90dffaad48e..0b43ac7c673 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/SymptomService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/SymptomService.java @@ -19,10 +19,10 @@ package org.sormas.e2etests.entities.services; import static org.sormas.e2etests.entities.pojo.helpers.ShortUUIDGenerator.generateShortUUID; -import static org.sormas.e2etests.enums.JaNeinUnbekanntOptions.*; import static org.sormas.e2etests.enums.YesNoUnknownOptions.NO; import static org.sormas.e2etests.enums.YesNoUnknownOptions.UNKNOWN; import static org.sormas.e2etests.enums.YesNoUnknownOptions.YES; +import static org.sormas.e2etests.enums.YesNoUnknownOptionsDE.*; import com.google.inject.Inject; import java.time.LocalDate; @@ -166,7 +166,7 @@ public Symptoms buildEditGeneratedSymptomsWithUnknownOptions() { } @SneakyThrows - public Symptoms buildEditGeneratedSymptomsSurvnet() { + public Symptoms buildEditGeneratedSymptomsSurvnetDE() { return Symptoms.builder() .maximumBodyTemperatureInC("35,2") .sourceOfBodyTemperature("rektal") @@ -198,62 +198,62 @@ public Symptoms buildEditGeneratedSymptomsSurvnet() { } @SneakyThrows - public Symptoms buildEditGeneratedSymptomsSurvnetWithNEINOptions() { + public Symptoms buildEditGeneratedSymptomsSurvnetWithNoOptionsDE() { return Symptoms.builder() - .maximumBodyTemperatureInC("35,2") - .sourceOfBodyTemperature("rektal") - .fever(NEIN.toString()) - .shivering(NEIN.toString()) - .headache(NEIN.toString()) - .musclePain(NEIN.toString()) - .feelingIll(NEIN.toString()) - .chillsOrSweats(NEIN.toString()) - .acuteRespiratoryDistressSyndrome(NEIN.toString()) - .soreThroat(NEIN.toString()) - .cough(NEIN.toString()) - .runnyNose(NEIN.toString()) - .pneumoniaClinicalOrRadiologic(NEIN.toString()) - .respiratoryDiseaseVentilation(NEIN.toString()) - .oxygenSaturationLower94(NEIN.toString()) - .rapidBreathing(NEIN.toString()) - .difficultyBreathing(NEIN.toString()) - .fastHeartRate(NEIN.toString()) - .diarrhea(NEIN.toString()) - .nausea(NEIN.toString()) - .lossOfSmell(NEIN.toString()) - .lossOfTaste(NEIN.toString()) - .otherNonHemorrhagicSymptoms(NEIN.toString()) - .symptomsComments(generateShortUUID()) - .build(); + .maximumBodyTemperatureInC("35,2") + .sourceOfBodyTemperature("rektal") + .fever(NEIN.toString()) + .shivering(NEIN.toString()) + .headache(NEIN.toString()) + .musclePain(NEIN.toString()) + .feelingIll(NEIN.toString()) + .chillsOrSweats(NEIN.toString()) + .acuteRespiratoryDistressSyndrome(NEIN.toString()) + .soreThroat(NEIN.toString()) + .cough(NEIN.toString()) + .runnyNose(NEIN.toString()) + .pneumoniaClinicalOrRadiologic(NEIN.toString()) + .respiratoryDiseaseVentilation(NEIN.toString()) + .oxygenSaturationLower94(NEIN.toString()) + .rapidBreathing(NEIN.toString()) + .difficultyBreathing(NEIN.toString()) + .fastHeartRate(NEIN.toString()) + .diarrhea(NEIN.toString()) + .nausea(NEIN.toString()) + .lossOfSmell(NEIN.toString()) + .lossOfTaste(NEIN.toString()) + .otherNonHemorrhagicSymptoms(NEIN.toString()) + .symptomsComments(generateShortUUID()) + .build(); } @SneakyThrows - public Symptoms buildEditGeneratedSymptomsSurvnetWithUNBEKANNTOptions() { + public Symptoms buildEditGeneratedSymptomsSurvnetWithUnknownOptionsDE() { return Symptoms.builder() - .maximumBodyTemperatureInC("35,2") - .sourceOfBodyTemperature("rektal") - .fever(UNBEKANNT.toString()) - .shivering(UNBEKANNT.toString()) - .headache(UNBEKANNT.toString()) - .musclePain(UNBEKANNT.toString()) - .feelingIll(UNBEKANNT.toString()) - .chillsOrSweats(UNBEKANNT.toString()) - .acuteRespiratoryDistressSyndrome(UNBEKANNT.toString()) - .soreThroat(UNBEKANNT.toString()) - .cough(UNBEKANNT.toString()) - .runnyNose(UNBEKANNT.toString()) - .pneumoniaClinicalOrRadiologic(UNBEKANNT.toString()) - .respiratoryDiseaseVentilation(UNBEKANNT.toString()) - .oxygenSaturationLower94(UNBEKANNT.toString()) - .rapidBreathing(UNBEKANNT.toString()) - .difficultyBreathing(UNBEKANNT.toString()) - .fastHeartRate(UNBEKANNT.toString()) - .diarrhea(UNBEKANNT.toString()) - .nausea(UNBEKANNT.toString()) - .lossOfSmell(UNBEKANNT.toString()) - .lossOfTaste(UNBEKANNT.toString()) - .otherNonHemorrhagicSymptoms(UNBEKANNT.toString()) - .symptomsComments(generateShortUUID()) - .build(); + .maximumBodyTemperatureInC("35,2") + .sourceOfBodyTemperature("rektal") + .fever(UNBEKANNT.toString()) + .shivering(UNBEKANNT.toString()) + .headache(UNBEKANNT.toString()) + .musclePain(UNBEKANNT.toString()) + .feelingIll(UNBEKANNT.toString()) + .chillsOrSweats(UNBEKANNT.toString()) + .acuteRespiratoryDistressSyndrome(UNBEKANNT.toString()) + .soreThroat(UNBEKANNT.toString()) + .cough(UNBEKANNT.toString()) + .runnyNose(UNBEKANNT.toString()) + .pneumoniaClinicalOrRadiologic(UNBEKANNT.toString()) + .respiratoryDiseaseVentilation(UNBEKANNT.toString()) + .oxygenSaturationLower94(UNBEKANNT.toString()) + .rapidBreathing(UNBEKANNT.toString()) + .difficultyBreathing(UNBEKANNT.toString()) + .fastHeartRate(UNBEKANNT.toString()) + .diarrhea(UNBEKANNT.toString()) + .nausea(UNBEKANNT.toString()) + .lossOfSmell(UNBEKANNT.toString()) + .lossOfTaste(UNBEKANNT.toString()) + .otherNonHemorrhagicSymptoms(UNBEKANNT.toString()) + .symptomsComments(generateShortUUID()) + .build(); } } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/SymptomsTabSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/SymptomsTabSteps.java index f954d50f457..cc69f021085 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/SymptomsTabSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/SymptomsTabSteps.java @@ -206,29 +206,28 @@ public SymptomsTabSteps( }); When( - "I change all symptoms fields to {string} option field and save on Survnet", + "I change all symptoms fields to {string} option field and save for Survnet DE", (String option) -> { switch (option) { case "NO": - break; - case "NO_AND_OTHER_SYMPTOMS_TO_YES": + symptoms = symptomService.buildEditGeneratedSymptomsSurvnetWithNoOptionsDE(); + FillSymptomsDataSurvnet(symptoms); + webDriverHelpers.clickOnWebElementBySelector(SAVE_BUTTON); break; case "UNKNOWN": + symptoms = symptomService.buildEditGeneratedSymptomsSurvnetWithUnknownOptionsDE(); + FillSymptomsDataSurvnet(symptoms); + webDriverHelpers.clickOnWebElementBySelector(SAVE_BUTTON); break; - case "JA": - symptoms = symptomService.buildEditGeneratedSymptomsSurvnet(); + case "YES": + symptoms = symptomService.buildEditGeneratedSymptomsSurvnetDE(); FillSymptomsDataSurvnet(symptoms); - fillOtherSymptoms( - symptoms.getSymptomsComments()); // otherNonHemorrhagicSymptomsText field conected - // with selectOtherClinicalSymptoms //not mapped - selectFistSymptom(symptoms.getFirstSymptom()); // not mapped - fillOtherSymptoms(symptoms.getSymptomsComments()); //notmapped - fillSymptomsComments(symptoms.getSymptomsComments()); //not mapped - + fillOtherSymptoms(symptoms.getSymptomsComments()); + selectFistSymptom(symptoms.getFirstSymptom()); + fillOtherSymptoms(symptoms.getSymptomsComments()); + fillSymptomsComments(symptoms.getSymptomsComments()); fillDateOfSymptomDE(symptoms.getDateOfSymptom(), Locale.GERMAN); webDriverHelpers.clickOnWebElementBySelector(SAVE_BUTTON); - - // Todo obluzenuie ponizszego capture(CATEGORY_SAVED_POPUP) webDriverHelpers.waitUntilElementIsVisibleAndClickable(CATEGORY_SAVED_POPUP); webDriverHelpers.clickOnWebElementBySelector(CATEGORY_SAVED_POPUP); break; @@ -278,25 +277,6 @@ public SymptomsTabSteps( selectFever(option); }); - And( - "^I set \"([^\"]*)\" Symptoms to \"([^\"]*)\" on the Symptoms tab$", - (String symptom, String option) -> { - switch (symptom) { - case "Fever": - selectFever(option); - break; - case "Shivering": - selectShivering(option); - break; - } - }); - - And( - "^I collect \"([^\"]*)\" Symptoms checkbox value from the Symptoms tab", - (String option) -> { - selectFever(option); - }); - And( "^I set Date of symptom onset to (\\d+) days before the vaccination date on the Symptoms tab for DE$", (Integer numberOfDays) -> { @@ -380,67 +360,6 @@ private void FillSymptomsData(Symptoms symptoms) { selectFistSymptom(symptoms.getFirstSymptom()); } - private void FillSymptomsDataSurvnet(Symptoms symptoms) { - selectMaximumBodyTemperatureInCCombobox(symptoms.getMaximumBodyTemperatureInC()); - selectSourceOfBodyTemperature(symptoms.getSourceOfBodyTemperature()); - // selectFever(symptoms.getFever()); --ok - // selectShivering(symptoms.getShivering()); --ok - // selectHeadache(symptoms.getHeadache()); --oh - // selectMusclePain(symptoms.getMusclePain()); --ok - // selectFeelingIll(symptoms.getFeelingIll()); --ok - // selectChillsOrSweats(symptoms.getChillsOrSweats()); --ok - // selectAcuteRespiratoryDistressSyndrome(symptoms.getAcuteRespiratoryDistressSyndrome()); - // selectSoreThroat(symptoms.getSoreThroat()); --ok - // selectCough(symptoms.getCough()); --ok - // selectRunnyNose(symptoms.getRunnyNose()); --ok - // selectPneumoniaClinicalOrRadiologic(symptoms.getPneumoniaClinicalOrRadiologic()); - // selectRespiratoryDiseaseVentilation(symptoms.getRespiratoryDiseaseVentilation()); - // selectOxygenSaturationLower94(symptoms.getOxygenSaturationLower94()); --not mapped - // selectRapidBreathing(symptoms.getRapidBreathing()); --ok - // selectDifficultyBreathing(symptoms.getDifficultyBreathing()); --ok - // selectFastHeartRate(symptoms.getFastHeartRate()); --ok - // selectDiarrhea(symptoms.getDiarrhea()); --ok - // selectNausea(symptoms.getNausea()); --ok - // selectLossOfSmell(symptoms.getLossOfSmell()); --ok - // selectLossOfTaste(symptoms.getLossOfTaste()); --ok - selectOtherClinicalSymptoms(symptoms.getOtherNonHemorrhagicSymptoms()); - - // selectChillsOrSweats(symptoms.getChillsOrSweats()); - // selectHeadache(symptoms.getHeadache()); - // selectMusclePain(symptoms.getMusclePain()); - // selectAcuteRespiratoryDistressSyndrome(symptoms.getAcuteRespiratoryDistressSyndrome()); - // selectCough(symptoms.getCough()); - // selectPneumoniaClinicalOrRadiologic(symptoms.getPneumoniaClinicalOrRadiologic()); - // selectDifficultyBreathing(symptoms.getDifficultyBreathing()); - // selectRapidBreathing(symptoms.getRapidBreathing()); - // selectRunnyNose(symptoms.getRunnyNose()); - // selectSoreThroat(symptoms.getSoreThroat()); - // selectDiarrhea(symptoms.getDiarrhea()); - // selectNausea(symptoms.getNausea()); - // selectLossOfSmell(symptoms.getLossOfSmell()); - // selectLossOfTaste(symptoms.getLossOfTaste()); - // selectOtherClinicalSymptoms(symptoms.getOtherNonHemorrhagicSymptoms()); - // selectAbnormalLungXrayFindings(symptoms.getAbnormalLungXrayFindings()); - // selectFatigueWeakness(symptoms.getFatigueWeakness()); - // selectJointPain(symptoms.getJointPain()); - // selectCoughWithHeamoptysis(symptoms.getCoughWithHeamoptysis()); - // selectCoughWithSputum(symptoms.getCoughWithSputum()); - // selectFluidInLungCavityXray(symptoms.getFluidInLungCavityXray()); - // selectFluidInLungCavityAuscultation(symptoms.getFluidInLungCavityAuscultation()); - // selectInDrawingOfChestWall(symptoms.getInDrawingOfChestWall()); - // selectAbdominalPain(symptoms.getAbdominalPain()); - // selectVomiting(symptoms.getVomiting()); - // selectSkinUlcers(symptoms.getSkinUlcers()); - // selectUnexplainedBleeding(symptoms.getUnexplainedBleeding()); - // selectComa(symptoms.getComa()); - // selectLymphadenopathy(symptoms.getLymphadenopathy()); - // selectInabilityToWalk(symptoms.getInabilityToWalk()); - // selectSkinRash(symptoms.getSkinRash()); - // selectConfusedDisoriented(symptoms.getConfusedDisoriented()); - // selectSeizures(symptoms.getSeizures()); - // selectFistSymptom(symptoms.getFirstSymptom()); - } - private void FillSymptomsDataForNoUnknown(Symptoms symptoms) { selectMaximumBodyTemperatureInCCombobox(symptoms.getMaximumBodyTemperatureInC()); selectSourceOfBodyTemperature(symptoms.getSourceOfBodyTemperature()); @@ -480,6 +399,32 @@ private void FillSymptomsDataForNoUnknown(Symptoms symptoms) { selectOtherComplications(symptoms.getOtherComplications()); } + private void FillSymptomsDataSurvnet(Symptoms symptoms) { + selectMaximumBodyTemperatureInCCombobox(symptoms.getMaximumBodyTemperatureInC()); + selectSourceOfBodyTemperature(symptoms.getSourceOfBodyTemperature()); + selectFever(symptoms.getFever()); + selectShivering(symptoms.getShivering()); + selectHeadache(symptoms.getHeadache()); + selectMusclePain(symptoms.getMusclePain()); + selectFeelingIll(symptoms.getFeelingIll()); + selectChillsOrSweats(symptoms.getChillsOrSweats()); + selectAcuteRespiratoryDistressSyndrome(symptoms.getAcuteRespiratoryDistressSyndrome()); + selectSoreThroat(symptoms.getSoreThroat()); + selectCough(symptoms.getCough()); + selectRunnyNose(symptoms.getRunnyNose()); + selectPneumoniaClinicalOrRadiologic(symptoms.getPneumoniaClinicalOrRadiologic()); + selectRespiratoryDiseaseVentilation(symptoms.getRespiratoryDiseaseVentilation()); + selectOxygenSaturationLower94(symptoms.getOxygenSaturationLower94()); + selectRapidBreathing(symptoms.getRapidBreathing()); + selectDifficultyBreathing(symptoms.getDifficultyBreathing()); + selectFastHeartRate(symptoms.getFastHeartRate()); + selectDiarrhea(symptoms.getDiarrhea()); + selectNausea(symptoms.getNausea()); + selectLossOfSmell(symptoms.getLossOfSmell()); + selectLossOfTaste(symptoms.getLossOfTaste()); + selectOtherClinicalSymptoms(symptoms.getOtherNonHemorrhagicSymptoms()); + } + private Symptoms collectSymptomsData() { return Symptoms.builder() diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java index b18044b03b6..78288321c4f 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java @@ -91,43 +91,6 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { softly.assertAll(); }); - And( - "I check if \"([^\"]*)\" SYMPTOMS in SORMAS generated single XML file is correctS", - (String symptom) -> { - // ToDO -consider to change all expecrted... to mor global expectedValue !!! - String expectedValue = null; - String symptomOption; - String symptomUI; - - switch (symptom) { - case "Fever": - // String symptomOption = getValueFromSpecificFieldByName(singleXmlFile, - // "Symptom0088"); - // String symptomUI = symptoms.getFever(); - - // if (symptomUI == "JA") expectedValue = "true"; - // else expectedValue = "false"; - - // softly.assertEquals(feverOption, expectedValue, "Fever checkbox value is - // incorrect!"); - softly.assertAll(); - break; - case "Shivering": - String expectedShivering = null; - String shiveringOption = - getValueFromSpecificFieldByName(singleXmlFile, "Symptom0101"); - String symptomShivering = symptoms.getFever(); - - if (symptomShivering == "JA") expectedShivering = "true"; - else expectedShivering = "false"; - - softly.assertEquals( - shiveringOption, expectedShivering, "Shivering checkbox value is incorrect!"); - softly.assertAll(); - break; - } - }); - And( "I check if \"([^\"]*)\" SYMPTOM in SORMAS generated single XML file is correct", (String symptom) -> { @@ -135,288 +98,277 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { String expectedValue = null; switch (symptom) { case "Fever": - String expectedFever = null; - String feverOption = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0088"); - String symptomFever = symptoms.getFever(); + String feverOptionFromXml = + getValueFromSpecificFieldByName(singleXmlFile, "Symptom0088"); + String feverOptionFromUI = symptoms.getFever(); - if (symptomFever == "JA") expectedFever = "true"; - else expectedFever = "false"; + if (feverOptionFromUI == "JA") expectedValue = "true"; + else expectedValue = "false"; - softly.assertEquals(feverOption, expectedFever, "Fever checkbox value is incorrect!"); + softly.assertEquals( + feverOptionFromXml, expectedValue, symptom + " checkbox value is incorrect!"); softly.assertAll(); break; case "Shivering": - String expectedShivering = null; - String shiveringOption = + String shiveringOptionFromXml = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0101"); - String symptomShivering = symptoms.getFever(); + String shiveringOptionFromUI = symptoms.getFever(); - if (symptomShivering == "JA") expectedShivering = "true"; - else expectedShivering = "false"; + if (shiveringOptionFromUI == "JA") expectedValue = "true"; + else expectedValue = "false"; softly.assertEquals( - shiveringOption, expectedShivering, "Shivering checkbox value is incorrect!"); + shiveringOptionFromXml, expectedValue, symptom + " checkbox value is incorrect!"); softly.assertAll(); break; case "Headache": - String expectedHeadache = null; - String headacheOption = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0101"); - String symptomHeadache = symptoms.getHeadache(); + String headacheOptionFromXml = + getValueFromSpecificFieldByName(singleXmlFile, "Symptom0101"); + String headacheOptionFromUI = symptoms.getHeadache(); - if (symptomHeadache == "JA") expectedHeadache = "true"; - else expectedHeadache = "false"; + if (headacheOptionFromUI == "JA") expectedValue = "true"; + else expectedValue = "false"; softly.assertEquals( - headacheOption, expectedHeadache, "Headache checkbox value is incorrect!"); + headacheOptionFromXml, + expectedValue, + symptom + " Headache checkbox value is incorrect!"); softly.assertAll(); break; - case "MusclePain": - String expectedMusclePain = null; - String musclePaineOption = + case "Muscle Pain": + String musclePaineOptionFromXml = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0101"); - String symptomMusclePain = symptoms.getMusclePain(); + String musclePaineOptionFromUI = symptoms.getMusclePain(); - if (symptomMusclePain == "JA") expectedMusclePain = "true"; - else expectedMusclePain = "false"; + if (musclePaineOptionFromUI == "JA") expectedValue = "true"; + else expectedValue = "false"; softly.assertEquals( - musclePaineOption, expectedMusclePain, "MusclePain checkbox value is incorrect!"); + musclePaineOptionFromXml, + expectedValue, + symptom + " checkbox value is incorrect!"); softly.assertAll(); break; - case "FeelingIll": - String expectedFeelingIll = null; - String feelingIllOption = + case "Feeling Ill": + String feelingIllOptionFromXml = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0101"); - String symptomFeelingIll = symptoms.getFeelingIll(); + String feelingIllOptionFromUI = symptoms.getFeelingIll(); - if (symptomFeelingIll == "JA") expectedFeelingIll = "true"; - else expectedFeelingIll = "false"; + if (feelingIllOptionFromUI == "JA") expectedValue = "true"; + else expectedValue = "false"; softly.assertEquals( - feelingIllOption, expectedFeelingIll, "FeelingIll checkbox value is incorrect!"); + feelingIllOptionFromXml, + expectedValue, + symptom + " checkbox value is incorrect!"); softly.assertAll(); break; - case "ChillsSweats": + case "Chills Sweats": System.out.print("Not mapped to xml !!!"); break; - case "AcuteRespiratoryDistressSyndrome": - String expectedAcuteRespiratoryDistressSyndrome = null; - String acuteRespiratoryDistressSyndromeOption = + case "Acute Respiratory Distress Syndrome": + String acuteRespiratoryDistressSyndromeOptionFromXml = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0394"); - String symptomAcuteRespiratoryDistressSyndrome = + String acuteRespiratoryDistressSyndromeOptionFromUI = symptoms.getAcuteRespiratoryDistressSyndrome(); - if (symptomAcuteRespiratoryDistressSyndrome == "JA") - expectedAcuteRespiratoryDistressSyndrome = "true"; - else expectedAcuteRespiratoryDistressSyndrome = "false"; + if (acuteRespiratoryDistressSyndromeOptionFromUI == "JA") expectedValue = "true"; + else expectedValue = "false"; softly.assertEquals( - acuteRespiratoryDistressSyndromeOption, - expectedAcuteRespiratoryDistressSyndrome, - "AcuteRespiratoryDistressSyndrome checkbox value is incorrect!"); + acuteRespiratoryDistressSyndromeOptionFromXml, + expectedValue, + symptom + "AcuteRespiratoryDistressSyndrome checkbox value is incorrect!"); softly.assertAll(); break; - case "SoreThroat": - String expectedSoreThroat = null; - String soreThroatOption = + case "Sore Throat": + String soreThroatOptionFromXml = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0103"); - String symptomSoreThroat = symptoms.getSoreThroat(); + String soreThroatOptionFromUI = symptoms.getSoreThroat(); - if (symptomSoreThroat == "JA") expectedSoreThroat = "true"; - else expectedSoreThroat = "false"; + if (soreThroatOptionFromUI == "JA") expectedValue = "true"; + else expectedValue = "false"; softly.assertEquals( - soreThroatOption, expectedSoreThroat, "SoreThroat checkbox value is incorrect!"); + soreThroatOptionFromXml, + expectedValue, + symptom + " checkbox value is incorrect!"); softly.assertAll(); break; case "Cough": - String expectedCough = null; - String coughOption = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0130"); - String symptomCought = symptoms.getCough(); + String coughOptionFromXml = + getValueFromSpecificFieldByName(singleXmlFile, "Symptom0130"); + String coughOptionFromUI = symptoms.getCough(); - if (symptomCought == "JA") expectedCough = "true"; - else expectedCough = "false"; + if (coughOptionFromUI == "JA") expectedValue = "true"; + else expectedValue = "false"; - softly.assertEquals(coughOption, expectedCough, "Cough checkbox value is incorrect!"); + softly.assertEquals( + coughOptionFromXml, expectedValue, symptom + " checkbox value is incorrect!"); softly.assertAll(); break; - case "RunnyNose": - String expectedRunnyNose = null; - String runnyNoseOption = + case "Runny Nose": + String runnyNoseOptionFromXml = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0225"); - String symptomRunnyNose = symptoms.getRunnyNose(); + String runnyNoseOptionFromUI = symptoms.getRunnyNose(); - if (symptomRunnyNose == "JA") expectedRunnyNose = "true"; - else expectedRunnyNose = "false"; + if (runnyNoseOptionFromUI == "JA") expectedValue = "true"; + else expectedValue = "false"; softly.assertEquals( - runnyNoseOption, expectedRunnyNose, "RunnyNose checkbox value is incorrect!"); + runnyNoseOptionFromXml, expectedValue, symptom + " checkbox value is incorrect!"); softly.assertAll(); break; - case "PneumoniaClinicalOrRadiologic": - String expectedPneumoniaClinicalOrRadiologic = null; - String pneumoniaClinicalOrRadiologicOption = + case "Pneumonia Clinical Or Radiologic": + String pneumoniaClinicalOrRadiologicOptionFromXml = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0158"); - String symptomPneumoniaClinicalOrRadiologic = + String pneumoniaClinicalOrRadiologicOptionFromUI = symptoms.getPneumoniaClinicalOrRadiologic(); - if (symptomPneumoniaClinicalOrRadiologic == "JA") - expectedPneumoniaClinicalOrRadiologic = "true"; - else expectedPneumoniaClinicalOrRadiologic = "false"; + if (pneumoniaClinicalOrRadiologicOptionFromUI == "JA") expectedValue = "true"; + else expectedValue = "false"; softly.assertEquals( - pneumoniaClinicalOrRadiologicOption, - expectedPneumoniaClinicalOrRadiologic, - "PneumoniaClinicalOrRadiologic checkbox value is incorrect!"); + pneumoniaClinicalOrRadiologicOptionFromXml, + expectedValue, + symptom + " checkbox value is incorrect!"); softly.assertAll(); break; - case "RespiratoryDiseaseVentilation": - String expectedRespiratoryDiseaseVentilation = null; - String respiratoryDiseaseVentilationOption = + case "Respiratory Disease Ventilation": + String respiratoryDiseaseVentilationOptionFromXml = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0393"); - String symptomRespiratoryDiseaseVentilation = + String respiratoryDiseaseVentilationOptionFromUI = symptoms.getRespiratoryDiseaseVentilation(); - if (symptomRespiratoryDiseaseVentilation == "JA") - expectedRespiratoryDiseaseVentilation = "true"; - else expectedRespiratoryDiseaseVentilation = "false"; + if (respiratoryDiseaseVentilationOptionFromUI == "JA") expectedValue = "true"; + else expectedValue = "false"; softly.assertEquals( - respiratoryDiseaseVentilationOption, - expectedRespiratoryDiseaseVentilation, - "RespiratoryDiseaseVentilation checkbox value is incorrect!"); + respiratoryDiseaseVentilationOptionFromXml, + expectedValue, + symptom + " checkbox value is incorrect!"); softly.assertAll(); break; - case "oxygenSaturationLower94": + case "Oxygen Saturation Lower94": System.out.print("Not mapped to xml !!!"); break; - case "RapidBreathing": - String expectedRapidBreathing = null; - String rapidBreathingOption = + case "Rapid Breathing": + String rapidBreathingOptionFromXml = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0418"); - String symptomRapidBreathing = symptoms.getRapidBreathing(); + String rapidBreathingOptionFromUI = symptoms.getRapidBreathing(); - if (symptomRapidBreathing == "JA") expectedRapidBreathing = "true"; - else expectedRapidBreathing = "false"; + if (rapidBreathingOptionFromUI == "JA") expectedValue = "true"; + else expectedValue = "false"; softly.assertEquals( - rapidBreathingOption, - expectedRapidBreathing, - "RapidBreathing checkbox value is incorrect!"); + rapidBreathingOptionFromXml, + expectedValue, + symptom + " checkbox value is incorrect!"); softly.assertAll(); break; - case "DifficultyBreathing": - String expecteDdifficultyBreathing = null; - String difficultyBreathingOption = + case "Difficulty Breathing": + String difficultyBreathingOptionFromXml = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0064"); - String symptomDifficultyBreathing = symptoms.getDifficultyBreathing(); + String difficultyBreathingOptionFromUI = symptoms.getDifficultyBreathing(); - if (symptomDifficultyBreathing == "JA") expecteDdifficultyBreathing = "true"; - else expecteDdifficultyBreathing = "false"; + if (difficultyBreathingOptionFromUI == "JA") expectedValue = "true"; + else expectedValue = "false"; softly.assertEquals( - difficultyBreathingOption, - expecteDdifficultyBreathing, - "RapidBreathing checkbox value is incorrect!"); + difficultyBreathingOptionFromXml, + expectedValue, + symptom + " checkbox value is incorrect!"); softly.assertAll(); break; - case "FastHeartRate": - String expectedFastHeartRate = null; - String fastHeartRateOption = + case "Fast Heart Rate": + String fastHeartRateOptionFromXml = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0245"); - String symptomFastHeartRate = symptoms.getFastHeartRate(); + String fastHeartRateOptionFromUI = symptoms.getFastHeartRate(); - if (symptomFastHeartRate == "JA") expectedFastHeartRate = "true"; - else expectedFastHeartRate = "false"; + if (fastHeartRateOptionFromUI == "JA") expectedValue = "true"; + else expectedValue = "false"; softly.assertEquals( - fastHeartRateOption, - expectedFastHeartRate, - "FastHeartRate checkbox value is incorrect!"); + fastHeartRateOptionFromXml, + expectedValue, + symptom + " checkbox value is incorrect!"); softly.assertAll(); break; case "Diarrhea": - String expectedDiarrhea = null; - String diarrheaOption = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0062"); - String symptomDiarrhea = symptoms.getDiarrhea(); + String diarrheaOptionFromXml = + getValueFromSpecificFieldByName(singleXmlFile, "Symptom0062"); + String diarrheaOptionFromUI = symptoms.getDiarrhea(); - if (symptomDiarrhea == "JA") expectedDiarrhea = "true"; - else expectedDiarrhea = "false"; + if (diarrheaOptionFromUI == "JA") expectedValue = "true"; + else expectedValue = "false"; softly.assertEquals( - diarrheaOption, expectedDiarrhea, "Diarrhea checkbox value is incorrect!"); + diarrheaOptionFromXml, expectedValue, symptom + " checkbox value is incorrect!"); softly.assertAll(); break; case "Nausea": - String expectedNausea = null; - String nauseaOption = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0101"); - String symptomNausea = symptoms.getNausea(); + String nauseaOptionFromXml = + getValueFromSpecificFieldByName(singleXmlFile, "Symptom0101"); + String nauseaOptionFromUI = symptoms.getNausea(); - if (symptomNausea == "JA") expectedNausea = "true"; - else expectedNausea = "false"; + if (nauseaOptionFromUI == "JA") expectedValue = "true"; + else expectedValue = "false"; softly.assertEquals( - nauseaOption, expectedNausea, symptom + " checkbox value is incorrect!"); + nauseaOptionFromXml, expectedValue, symptom + " checkbox value is incorrect!"); softly.assertAll(); break; - case "LossOfSmell": - String expectedLossOfSmell = null; - String lossOfSmellOption = + case "Loss Of Smell": + String lossOfSmellOptionfromXml = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0416"); - String symptomLossOfSmell = symptoms.getLossOfSmell(); + String lossOfSmellOptionfromUI = symptoms.getLossOfSmell(); - if (symptomLossOfSmell == "JA") expectedLossOfSmell = "true"; - else expectedLossOfSmell = "false"; + if (lossOfSmellOptionfromUI == "JA") expectedValue = "true"; + else expectedValue = "false"; softly.assertEquals( - lossOfSmellOption, - expectedLossOfSmell, + lossOfSmellOptionfromXml, + expectedValue, symptom + " checkbox value is incorrect!"); softly.assertAll(); break; - case "LossOfTaste": - String expectedLossOfTaste = null; - String lossOfTasteOption = + case "Loss OfTaste": + String lossOfTasteOptionFromXml = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0417"); - String symptomLossOfTaste = symptoms.getLossOfTaste(); + String lossOfTasteOptionFromUI = symptoms.getLossOfTaste(); - if (symptomLossOfTaste == "JA") expectedLossOfTaste = "true"; - else expectedLossOfTaste = "false"; + if (lossOfTasteOptionFromUI == "JA") expectedValue = "true"; + else expectedValue = "false"; softly.assertEquals( - lossOfTasteOption, - expectedLossOfTaste, + lossOfTasteOptionFromXml, + expectedValue, symptom + " checkbox value is incorrect!"); softly.assertAll(); break; - case "OtherNonHemorrhagicSymptoms": - String expectedOtherNonHemorrhagicSymptoms = null; - String otherNonHemorrhagicSymptomsOption = + case "Other Non Hemorrhagic Symptoms": + String otherNonHemorrhagicSymptomsOptionFromXml = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0101"); - String symptomOtherNonHemorrhagicSymptoms = symptoms.getOtherNonHemorrhagicSymptoms(); + String otherNonHemorrhagicSymptomsOptionFromUI = + symptoms.getOtherNonHemorrhagicSymptoms(); - if (symptomOtherNonHemorrhagicSymptoms == "JA") - expectedOtherNonHemorrhagicSymptoms = "true"; - else expectedOtherNonHemorrhagicSymptoms = "false"; + if (otherNonHemorrhagicSymptomsOptionFromUI == "JA") expectedValue = "true"; + else expectedValue = "false"; softly.assertEquals( - otherNonHemorrhagicSymptomsOption, - expectedOtherNonHemorrhagicSymptoms, + otherNonHemorrhagicSymptomsOptionFromXml, + expectedValue, symptom + " checkbox value is incorrect!"); softly.assertAll(); break; - case "otherNonHemorrhagicSymptomsText": // mandatory comment field for - // OtherNonHemorrhagicSymptoms!!! - System.out.print("Not mapped to xml !!!"); - break; - case "OnsetOfDisease": - String onsetOfDiseaseOptionDate = + case "Onset Of Disease": + String onsetOfDiseaseOptionDateFromXml = getValueFromSpecificFieldByName(singleXmlFile, "OnsetOfDisease").substring(0, 10); - String expectedOnsetOfDiseaseDate = symptoms.getDateOfSymptom().toString(); + String expectedOnsetOfDiseaseDateFromUI = symptoms.getDateOfSymptom().toString(); softly.assertEquals( - onsetOfDiseaseOptionDate, - expectedOnsetOfDiseaseDate, + onsetOfDiseaseOptionDateFromXml, + expectedOnsetOfDiseaseDateFromUI, symptom + " date value is incorrect!"); softly.assertAll(); break; @@ -520,14 +472,6 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { + ".xml"); }); - And( - "^I open locally SORMAS generated XML file for single message$", - () -> { - singleXmlFile = - XMLParser.getDocument( - "C:\\Sormas\\SORMAS-Project\\sormas-e2e-tests\\src\\main\\resources\\survnetXMLTemplates\\FeverShivering.xml"); - }); - And( "^I open SORMAS generated XML file for bulk case message$", () -> { @@ -598,7 +542,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { singleXmlFile = XMLParser.getDocument( "/srv/dockerdata/jenkins_new/sormas-files/event_" - + EditEventSteps.externalEventUUID.get(0).substring(1,37) + + EditEventSteps.externalEventUUID.get(0).substring(1, 37) + ".xml"); }); @@ -607,7 +551,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { () -> { softly.assertEquals( getGuidRecord(singleXmlFile, 0), - EditEventSteps.externalEventUUID.get(0).substring(1,37), + EditEventSteps.externalEventUUID.get(0).substring(1, 37), "External event UUID is incorrect!"); softly.assertAll(); }); diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature index 46c96895507..10f6f79ce6f 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature @@ -90,27 +90,110 @@ Feature: Survnet tests And I check if "date of report" for all 2 cases in SORMAS generated bulk XML file is correct @tmsLink=SORQA-1029 - Scenario: Symptoms in case when sending from SORMAS to Meldesoftware + Scenario: Symptoms in case when sending from SORMAS to Meldesoftware with YES checkbox option for Survnet DE Given I log in as a Survnet When I click on the Cases button from navbar And I click on the NEW CASE button - - And I open locally SORMAS generated XML file for single message - And I create a new case with mandatory data only for Survnet DE And I navigate to symptoms tab - Then I change all symptoms fields to "JA" option field and save on Survnet - # And I set "Fever" Symptoms to "JA" on the Symptoms tab - # And I set "Shivering" Symptoms to "JA" on the Symptoms tab - # And I save the Symptoms data + Then I change all symptoms fields to "YES" option field and save for Survnet DE And I navigate to case tab And I click on Send to reporting tool button on Edit Case page And I collect case external UUID from Edit Case page Then I wait 50 seconds for system reaction - # Then I open SORMAS generated XML file for single message - And I check if "OnsetOfDisease" SYMPTOM in SORMAS generated single XML file is correct + Then I open SORMAS generated XML file for single case message + And I check if "Fever" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Shivering" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Headache" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Muscle Pain" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Feeling Ill" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Chills Sweats" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Acute Respiratory Distress Syndrome" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Sore Throat" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Cough" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Runny Nose" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Pneumonia Clinical Or Radiologic" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Respiratory Disease Ventilation" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Oxygen Saturation Lower94" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Rapid Breathing" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Difficulty Breathing" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Fast Heart Rate" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Diarrhea" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Nausea" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Loss Of Smell" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Loss OfTaste" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Other Non Hemorrhagic Symptoms" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Onset Of Disease" SYMPTOM in SORMAS generated single XML file is correct + @tmsLink=SORQA-1029 + Scenario: Symptoms in case when sending from SORMAS to Meldesoftware with NO checkbox option for Survnet DE + Given I log in as a Survnet + When I click on the Cases button from navbar + And I click on the NEW CASE button + And I create a new case with mandatory data only for Survnet DE + And I navigate to symptoms tab + Then I change all symptoms fields to "NO" option field and save for Survnet DE + And I navigate to case tab + And I click on Send to reporting tool button on Edit Case page + And I collect case external UUID from Edit Case page + Then I wait 50 seconds for system reaction + And I open SORMAS generated XML file for single case message + And I check if "Fever" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Shivering" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Headache" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Muscle Pain" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Feeling Ill" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Chills Sweats" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Acute Respiratory Distress Syndrome" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Sore Throat" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Cough" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Runny Nose" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Pneumonia Clinical Or Radiologic" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Respiratory Disease Ventilation" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Oxygen Saturation Lower94" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Rapid Breathing" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Difficulty Breathing" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Fast Heart Rate" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Diarrhea" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Nausea" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Loss Of Smell" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Loss OfTaste" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Other Non Hemorrhagic Symptoms" SYMPTOM in SORMAS generated single XML file is correct + @tmsLink=SORQA-1029 + Scenario: Symptoms in case when sending from SORMAS to Meldesoftware with UNKNOWN checkbox option for Survnet DE + Given I log in as a Survnet + When I click on the Cases button from navbar + And I click on the NEW CASE button + And I create a new case with mandatory data only for Survnet DE + And I navigate to symptoms tab + Then I change all symptoms fields to "UNKNOWN" option field and save for Survnet DE + And I navigate to case tab + And I click on Send to reporting tool button on Edit Case page + And I collect case external UUID from Edit Case page + Then I wait 50 seconds for system reaction + And I open SORMAS generated XML file for single case message + And I check if "Fever" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Shivering" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Headache" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Muscle Pain" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Feeling Ill" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Chills Sweats" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Acute Respiratory Distress Syndrome" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Sore Throat" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Cough" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Runny Nose" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Pneumonia Clinical Or Radiologic" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Respiratory Disease Ventilation" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Oxygen Saturation Lower94" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Rapid Breathing" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Difficulty Breathing" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Fast Heart Rate" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Diarrhea" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Nausea" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Loss Of Smell" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Loss OfTaste" SYMPTOM in SORMAS generated single XML file is correct + And I check if "Other Non Hemorrhagic Symptoms" SYMPTOM in SORMAS generated single XML file is correct @tmsLink=SORQA-1027 Scenario: Calculated age in case when sending from SORMAS to Meldesoftware From 4ee029ad6cdab8d647c4e2bdeef5afefd4c0f2e0 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Tue, 11 Jul 2023 15:19:02 +0200 Subject: [PATCH 021/174] qu-auto/SORQA-979 Demis - Process a Lab message that has multiple samples. New steps have been added. --- .../aCommonComponents/SideCards.java | 3 + .../messages/MessagesDirectoryPage.java | 1 + .../services/api/demis/DemisApiService.java | 3 +- .../steps/api/demisSteps/DemisSteps.java | 10 +++ .../aCommonComponents/SideCardsSteps.java | 35 ++++++++--- .../samples/CreateNewSampleSteps.java | 61 +++++++++--------- .../application/samples/EditSampleSteps.java | 63 ++++++++++++++++--- .../features/sanity/web/Case.feature | 2 +- .../features/sanity/web/DemisWeb.feature | 26 +++++++- .../features/sanity/web/Event.feature | 2 +- .../features/sanity/web/Sample.feature | 11 +--- 11 files changed, 154 insertions(+), 63 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/aCommonComponents/SideCards.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/aCommonComponents/SideCards.java index fa89ff6efe9..15630cb1175 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/aCommonComponents/SideCards.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/aCommonComponents/SideCards.java @@ -58,4 +58,7 @@ public static By checkTextInReportSideComponent(String text) { "//div[@location='sormasToSormas']//div[@class='v-slot v-slot-s-list-entry v-slot-s-list-entry-no-border']"); public static final By SHARE_SORMAS_2_SORMAS_POPUP_BUTTON = By.cssSelector(".popupContent #commit"); + public static By getEditSampleButtonByNumber(Integer number) { + return By.xpath(String.format("(//div[contains(@id, 'edit-sample')])[%x]", number)); + } } diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java index d5ad5737672..b3f159eb3ce 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java @@ -139,4 +139,5 @@ public static By getProcessStatusByIndex(int index) { public static final By NEW_SAMPLE_FORM_SECOND_PATHOGEN_LABORATORY_NAME = By.xpath("(//input[contains(@id, 'labDetails')])[3]"); public static final By MULTIPLE_SAMPLES_HEADER = By.xpath("//div[@class= 'v-window-header'][text()='Mehrere Proben']"); + public static final By CREATE_NEW_SAMPLE_CHECKBOX = By.xpath("//span[@class= 'v-radiobutton v-select-option']//label[text()='Neue Probe erstellen']"); } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java index 9a72a2997c7..a7e1d79040c 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java @@ -59,6 +59,7 @@ public class DemisApiService { private final String AUTHORIZATION_HEADER = "Authorization"; private final String CONTENT_TYPE_APPLICATION_JSON = "application/json"; private JSONObject jsonObject; + public static final String specimenUUID = UUID.randomUUID().toString(); @Inject public DemisApiService(RunningConfiguration runningConfiguration) { @@ -247,7 +248,7 @@ public String prepareLabNotificationFileWithTwoSamples( json = json.replace("\"\"", "\"" + patientFirstName + "\""); json = json.replace("\"\"", "\"" + patientLastName + "\""); json = json.replace("\"\"", "\"" + patientFirstName + "\""); - json = json.replace("", UUID.randomUUID().toString()); + json = json.replace("", specimenUUID); json = json.replace("", UUID.randomUUID().toString()); json = json.replace("", UUID.randomUUID().toString()); json = json.replace("", UUID.randomUUID().toString()); diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java index 376c51baa66..760392114d2 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java @@ -62,6 +62,7 @@ import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CREATE_A_NEW_CASE_WITH_POSITIVE_TEST_EVENT_PARTICIPANT_HEADER_DE; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CREATE_NEW_EVENT_PARTICIPANT_RADIOBUTTON_DE; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CREATE_NEW_PERSON_RADIOBUTTON_DE; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CREATE_NEW_SAMPLE_CHECKBOX; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.FIRST_PATHOGEN_LABORATORY_INPUT; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.FORWARDED_QUICK_FILTER_BUTTON; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.FORWARDED_QUICK_FILTER_COUNTER; @@ -99,6 +100,7 @@ import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.VERARBEITEN_BUTTON; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.checkMappedValueSelector; import static org.sormas.e2etests.pages.application.persons.PersonDirectoryPage.RESET_FILTERS_BUTTON; +import static org.sormas.e2etests.pages.application.samples.CreateNewSamplePage.SAVE_SAMPLE_BUTTON; import static org.sormas.e2etests.pages.application.samples.CreateNewSamplePage.TYPE_OF_TEST_INPUT; import static org.sormas.e2etests.pages.application.samples.EditSamplePage.PCR_TEST_SPECIFICATION_INPUT; import static org.sormas.e2etests.steps.BaseSteps.locale; @@ -924,6 +926,14 @@ public DemisSteps( webDriverHelpers.waitUntilIdentifiedElementIsPresent(POPUP_CONFIRM_BUTTON); webDriverHelpers.clickOnWebElementBySelector(POPUP_CONFIRM_BUTTON); }); + + And( + "^I pick a new sample in Pick or create sample popup during processing case$", + () -> { + webDriverHelpers.waitUntilIdentifiedElementIsPresent(CREATE_NEW_SAMPLE_CHECKBOX); + webDriverHelpers.clickOnWebElementBySelector(CREATE_NEW_SAMPLE_CHECKBOX); + webDriverHelpers.clickOnWebElementBySelector(SAVE_SAMPLE_BUTTON); + }); } private List> getTableRowsData() { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/aCommonComponents/SideCardsSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/aCommonComponents/SideCardsSteps.java index 917a0aec4c7..3d0527ac631 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/aCommonComponents/SideCardsSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/aCommonComponents/SideCardsSteps.java @@ -18,21 +18,33 @@ package org.sormas.e2etests.steps.web.application.aCommonComponents; -import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.*; -import static org.sormas.e2etests.pages.application.contacts.EditContactPage.NUMBER_OF_TESTS_IN_SAMPLES; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.ONE_TEST_IN_SAMPLES_DE; - import com.github.javafaker.Faker; import cucumber.api.java8.En; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.util.concurrent.TimeUnit; -import javax.inject.Inject; import lombok.SneakyThrows; import org.sormas.e2etests.helpers.WebDriverHelpers; import org.sormas.e2etests.steps.BaseSteps; import org.testng.asserts.SoftAssert; +import javax.inject.Inject; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.concurrent.TimeUnit; + +import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.ADDED_SAMPLES_IN_SAMPLE_CARD; +import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.EDIT_SAMPLE_BUTTON; +import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.HANDOVER_SIDE_CARD; +import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.LINKED_SHARED_ORGANIZATION_SELECTED_VALUE; +import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.REPORTS_DISPLAY_ASSOCIATED_EXTERNAL_MESSAGES_BUTTON; +import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.SAMPLES_DISPLAY_ASSOCIATED_LAB_MESSAGES_BUTTON; +import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.SHARE_SORMAS_2_SORMAS_POPUP_BUTTON; +import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.checkTextInHandoverSideComponent; +import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.checkTextInImmunizationSideComponent; +import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.checkTextInReportSideComponent; +import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.checkTextInSampleSideComponent; +import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.getEditSampleButtonByNumber; +import static org.sormas.e2etests.pages.application.contacts.EditContactPage.NUMBER_OF_TESTS_IN_SAMPLES; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.ONE_TEST_IN_SAMPLES_DE; + public class SideCardsSteps implements En { private final WebDriverHelpers webDriverHelpers; public static Faker faker; @@ -187,5 +199,12 @@ public SideCardsSteps( webDriverHelpers.clickOnWebElementBySelector(SHARE_SORMAS_2_SORMAS_POPUP_BUTTON); webDriverHelpers.waitForPageLoadingSpinnerToDisappear(30); }); + + And( + "^I click on edit sample icon of the (\\d+) displayed sample on Edit Case page$", + (Integer sampleNumber) -> { + webDriverHelpers.clickOnWebElementBySelector(getEditSampleButtonByNumber(sampleNumber)); + webDriverHelpers.waitForPageLoadingSpinnerToDisappear(30); + }); } } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/CreateNewSampleSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/CreateNewSampleSteps.java index 4d48edcfc6a..4ae53899059 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/CreateNewSampleSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/CreateNewSampleSteps.java @@ -18,6 +18,34 @@ package org.sormas.e2etests.steps.web.application.samples; +import com.github.javafaker.Faker; +import cucumber.api.java8.En; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; +import org.sormas.e2etests.entities.pojo.web.Sample; +import org.sormas.e2etests.entities.pojo.web.SampleAdditionalTest; +import org.sormas.e2etests.entities.services.SampleAdditionalTestService; +import org.sormas.e2etests.entities.services.SampleService; +import org.sormas.e2etests.enums.PathogenTestResults; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.state.ApiState; +import org.sormas.e2etests.steps.BaseSteps; +import org.testng.asserts.SoftAssert; + +import javax.inject.Inject; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.ACTION_CONFIRM_POPUP_BUTTON; import static org.sormas.e2etests.pages.application.cases.EditCasePage.SAMPLES_CARD_DATE_AND_TIME_OF_RESULT; import static org.sormas.e2etests.pages.application.cases.EditCasePage.SAMPLES_CARD_DATE_OF_COLLECTED_SAMPLE; @@ -119,33 +147,6 @@ import static org.sormas.e2etests.pages.application.samples.SamplesDirectoryPage.SAMPLE_RECEIVED_CHECKBOX; import static org.sormas.e2etests.pages.application.samples.SamplesDirectoryPage.SAMPLE_SHIPPED_CHECKBOX; -import com.github.javafaker.Faker; -import cucumber.api.java8.En; -import java.time.LocalDate; -import java.time.LocalTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import javax.inject.Inject; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; -import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; -import org.sormas.e2etests.entities.pojo.web.Sample; -import org.sormas.e2etests.entities.pojo.web.SampleAdditionalTest; -import org.sormas.e2etests.entities.services.SampleAdditionalTestService; -import org.sormas.e2etests.entities.services.SampleService; -import org.sormas.e2etests.enums.PathogenTestResults; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.state.ApiState; -import org.sormas.e2etests.steps.BaseSteps; -import org.testng.asserts.SoftAssert; - public class CreateNewSampleSteps implements En { public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("M/d/yyyy"); public static final DateTimeFormatter DATE_FORMATTER_DE = DateTimeFormatter.ofPattern("d.M.yyyy"); @@ -357,12 +358,12 @@ public CreateNewSampleSteps( }); When( - "^I validate the existence of two pathogen tests", - () -> { + "I validate the existence of {string} pathogen tests", + (String number) -> { TimeUnit.SECONDS.sleep(2); softly.assertEquals( webDriverHelpers.getNumberOfElements(EDIT_PATHOGEN_TEST), - 2, + number, "Number of pathogen tests is not correct"); softly.assertAll(); }); diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/EditSampleSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/EditSampleSteps.java index f6de5d21f8c..e39be64fd28 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/EditSampleSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/EditSampleSteps.java @@ -18,25 +18,60 @@ package org.sormas.e2etests.steps.web.application.samples; -import static org.sormas.e2etests.pages.application.samples.CreateNewSamplePage.SAVE_EDIT_SAMPLE_BUTTON; -import static org.sormas.e2etests.pages.application.samples.EditSamplePage.*; -import static org.sormas.e2etests.pages.application.samples.SamplesDirectoryPage.*; -import static org.sormas.e2etests.steps.BaseSteps.locale; - import cucumber.api.java8.En; -import java.time.LocalDate; -import java.time.LocalTime; -import java.time.format.DateTimeFormatter; -import javax.inject.Inject; import org.openqa.selenium.By; import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; import org.sormas.e2etests.entities.pojo.web.Sample; import org.sormas.e2etests.entities.services.SampleService; +import org.sormas.e2etests.entities.services.api.demis.DemisApiService; import org.sormas.e2etests.envconfig.manager.RunningConfiguration; import org.sormas.e2etests.helpers.WebDriverHelpers; import org.sormas.e2etests.state.ApiState; import org.testng.asserts.SoftAssert; +import javax.inject.Inject; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; + +import static org.sormas.e2etests.pages.application.samples.CreateNewSamplePage.SAVE_EDIT_SAMPLE_BUTTON; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.ADDIITONAL_NEW_TEST_RESULT_BUTTON; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.COLLECTED_DATE_TIME_COMBOBOX; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.COLLECTED_DATE_TIME_INPUT; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.COMMENT_AREA_INPUT; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.CQ_CT_VALUE_INPUT; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.DATE_SAMPLE_COLLECTED; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.DATE_SAMPLE_RECEIVED; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.DELETE_PATHOGEN_TEST_RESULT; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.DELETE_SAMPLE_BUTTON; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.DELETE_SAMPLE_REASON_POPUP; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.FIELD_SAMPLE_ID_INPUT; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.FOUR_FOLD_INCREASE_ANTIBODY_TITER; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.LABORATORY_COMBOBOX; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.LABORATORY_INPUT; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.LABORATORY_NAME_INPUT; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.LAB_SAMPLE_ID_INPUT; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.NEW_TEST_RESULT_DE; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.PATHOGEN_NEW_TEST_RESULT_BUTTON; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.PCR_TEST_SPECIFICATION_COMBOBOX; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.REASON_FOR_SAMPLING_TESTING_COMBOBOX; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.REASON_FOR_SAMPLING_TESTING_INPUT; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.RECEIVED_OPTION_BUTTON; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.SAMPLE_DELETION_POPUP_YES_BUTTON; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.SAMPLE_TYPE_COMBOBOX; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.SAMPLE_TYPE_INPUT; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.SAVE_SAMPLE_BUTTON; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.SEE_SAMPLES_FOR_THIS_PERSON_BUTTON_DE; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.SPECIFY_TEST_DETAILS_INPUT; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.SPECIMEN_CONDITION_COMBOBOX; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.SPECIMEN_CONDITION_INPUT; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.SPECIMEN_CONDITION_NOT_MANDATORY_COMBOBOX; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.TYPING_ID_INPUT; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.UUID_FIELD; +import static org.sormas.e2etests.pages.application.samples.SamplesDirectoryPage.SAMPLE_EDIT_PURPOSE_OPTIONS; +import static org.sormas.e2etests.pages.application.samples.SamplesDirectoryPage.SAMPLE_SEARCH_INPUT; +import static org.sormas.e2etests.steps.BaseSteps.locale; + public class EditSampleSteps implements En { public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("M/d/yyyy"); public static final DateTimeFormatter DATE_FORMATTER_DE = @@ -276,6 +311,16 @@ public EditSampleSteps( "Laboratory details are incorrect"); softly.assertAll(); }); + + Then( + "^I check that lab sample id match specimen id from Demis message on Edit Sample page$", + () -> { + softly.assertEquals( + webDriverHelpers.getValueFromWebElement(LAB_SAMPLE_ID_INPUT), + DemisApiService.specimenUUID, + "Sample id is incorrect"); + softly.assertAll(); + }); } private void selectPurposeOfSample(String samplePurpose, By element) { diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Case.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Case.feature index f109c6c19bd..1f0534fa289 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Case.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Case.feature @@ -1258,7 +1258,7 @@ Feature: Case end to end tests Then I navigate to the last created case via the url Then I validate only one sample is created with two pathogen tests Then I click on edit Sample - Then I validate the existence of two pathogen tests + Then I validate the existence of "2" pathogen tests @env_main @#8565 Scenario: Check an archived case if its read only diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index ce122444856..f42960cbc3c 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -499,15 +499,35 @@ Scenario: Create and send laboratory request via Demis And I choose create new case in Pick or create entry form for DE And I check that create new case form with pathogen detection reporting process is displayed for DE And I fill only mandatory fields to convert laboratory message into a case for DE - And I click on save button in the case popup + When I click on save button in the case popup Then I check that multiple samples window pops up And I confirm multiple samples window - Then I check that new sample form with pathogen detection reporting process is displayed + And I check that new sample form with pathogen detection reporting process is displayed And I click on save sample button And I click on save sample button And I click on save sample button + And I click on YES button in Update case disease variant popup window + And I pick a new sample in Pick or create sample popup during processing case + When I check that new sample form with pathogen detection reporting process is displayed + And I click on save sample button And I click on save sample button + And I click on YES button in Update case disease variant popup window And I click on the Cases button from navbar And I search the case by last created person via Demis message Then I click on the first Case ID from Case Directory - And I check if report side component in Edit Case has today date \ No newline at end of file + And I check that the number of added samples on the Edit case page is 2 + And I click on edit sample icon of the 1 displayed sample on Edit Case page + And I check that lab sample id match specimen id from Demis message on Edit Sample page + And I validate the existence of "2" pathogen tests + And I back to the cases list from edit case + When I click on edit sample icon of the 2 displayed sample on Edit Case page + Then I check that lab sample id match specimen id from Demis message on Edit Sample page + And I validate the existence of "1" pathogen tests + And I back to the cases list from edit case + And I check if report side component in Edit Case has today date + When I click on edit Report on Edit Case page + And I click on Display associated external messages button from Reports side component + And I check if external message window appears and close it + Then I click on the Messages button from navbar + And I filter by last created person via API in Messages Directory + And I verify that status for result 1 is set to processed in Message Directory page \ No newline at end of file diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature index 723acb14fa8..bde6f2d6699 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature @@ -883,7 +883,7 @@ Feature: Create events Then I navigate to a specific Event Participant of an Event based on UUID Then I validate only one sample is created with two pathogen tests Then I click on edit Sample - Then I validate the existence of two pathogen tests + Then I validate the existence of "2" pathogen tests @env_main @#8565 Scenario: Check an archived event if its read only diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Sample.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Sample.feature index dcf649a0b71..6ef56310b0c 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Sample.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Sample.feature @@ -143,13 +143,10 @@ Feature: Sample Functionalities @env_main @tmsLink=SORDEV-5493 Scenario: Add a Additional test from Samples and verify the fields Given API: I create a new person - And API: I check that POST call status code is 200 And API: I create a new case - And API: I check that POST call status code is 200 And API: I create a new sample - And API: I check that POST call status code is 200 When I log in as a Admin User And I click on the Sample button from navbar @@ -161,10 +158,8 @@ Feature: Sample Functionalities @#8556 @env_main Scenario: Add two positive Pathogen Test Result of different diseases to a Sample of a Contact Given API: I create a new person - And API: I check that POST call status code is 200 Then API: I create a new contact - And API: I check that POST call status code is 200 When I log in as a National User Then I open the last created contact via API @@ -184,15 +179,13 @@ Feature: Sample Functionalities Then I open the last created contact via API Then I validate only one sample is created with two pathogen tests Then I click on edit Sample - Then I validate the existence of two pathogen tests + Then I validate the existence of "2" pathogen tests @env_main @#8560 Scenario: Display date and time for pathogen test result on sample card Given API: I create a new person - And API: I check that POST call status code is 200 Then API: I create a new contact - And API: I check that POST call status code is 200 When I log in as a National User Then I open the last created contact via API @@ -253,10 +246,8 @@ Feature: Sample Functionalities @tmsLink=SORDEV-7427 @env_de Scenario: Test Make date fields in sample creation mask and information non-compulsory When API: I create a new person - And API: I check that POST call status code is 200 Then API: I create a new case - And API: I check that POST call status code is 200 Given I log in as a National User And I open the last created Case via API From 727d4599a4a800f149e3961b15db3508841f099d Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Tue, 11 Jul 2023 15:56:34 +0200 Subject: [PATCH 022/174] qu-auto/SORQA-979 Demis - Process a Lab message that has multiple samples. Assert for pathogen has been changed. --- .../steps/web/application/samples/CreateNewSampleSteps.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/CreateNewSampleSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/CreateNewSampleSteps.java index 4ae53899059..663ce528009 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/CreateNewSampleSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/CreateNewSampleSteps.java @@ -360,10 +360,11 @@ public CreateNewSampleSteps( When( "I validate the existence of {string} pathogen tests", (String number) -> { + int numberInt = Integer.parseInt(number); TimeUnit.SECONDS.sleep(2); softly.assertEquals( webDriverHelpers.getNumberOfElements(EDIT_PATHOGEN_TEST), - number, + numberInt, "Number of pathogen tests is not correct"); softly.assertAll(); }); From 2aa41a73522aa63835fb933611a9cdf5a1a3fa82 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Tue, 11 Jul 2023 16:40:34 +0200 Subject: [PATCH 023/174] qu-auto/SORQA-979 Demis - Process a Lab message that has multiple samples. New method to back to the case from sample edit page has been added. --- .../pages/application/samples/EditSamplePage.java | 1 + .../steps/web/application/samples/EditSampleSteps.java | 8 ++++++++ .../test/resources/features/sanity/web/DemisWeb.feature | 4 ++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/samples/EditSamplePage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/samples/EditSamplePage.java index 1cf36330280..dabd5c0aa14 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/samples/EditSamplePage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/samples/EditSamplePage.java @@ -81,4 +81,5 @@ public class EditSamplePage { By.cssSelector("[class='popupContent'] [id='pcrTestSpecification'] input"); public static final By SEE_SAMPLES_FOR_THIS_PERSON_BUTTON_DE = By.id("Proben f\u00FCr diese Person ansehen"); + public static final By BACK_TO_CASE_DE_BUTTON = By.xpath("//div[@class='v-link v-widget v-caption v-link-v-caption']//span[contains(text(), 'Fall')]"); } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/EditSampleSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/EditSampleSteps.java index e39be64fd28..8afdaa5d6c0 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/EditSampleSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/EditSampleSteps.java @@ -36,6 +36,7 @@ import static org.sormas.e2etests.pages.application.samples.CreateNewSamplePage.SAVE_EDIT_SAMPLE_BUTTON; import static org.sormas.e2etests.pages.application.samples.EditSamplePage.ADDIITONAL_NEW_TEST_RESULT_BUTTON; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.BACK_TO_CASE_DE_BUTTON; import static org.sormas.e2etests.pages.application.samples.EditSamplePage.COLLECTED_DATE_TIME_COMBOBOX; import static org.sormas.e2etests.pages.application.samples.EditSamplePage.COLLECTED_DATE_TIME_INPUT; import static org.sormas.e2etests.pages.application.samples.EditSamplePage.COMMENT_AREA_INPUT; @@ -321,6 +322,13 @@ public EditSampleSteps( "Sample id is incorrect"); softly.assertAll(); }); + + And( + "^I back to the case from Edit Sample page DE$", + () -> { + webDriverHelpers.scrollToElement(BACK_TO_CASE_DE_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(BACK_TO_CASE_DE_BUTTON); + }); } private void selectPurposeOfSample(String samplePurpose, By element) { diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index f42960cbc3c..ae5882e394e 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -519,11 +519,11 @@ Scenario: Create and send laboratory request via Demis And I click on edit sample icon of the 1 displayed sample on Edit Case page And I check that lab sample id match specimen id from Demis message on Edit Sample page And I validate the existence of "2" pathogen tests - And I back to the cases list from edit case + And I back to the case from Edit Sample page DE When I click on edit sample icon of the 2 displayed sample on Edit Case page Then I check that lab sample id match specimen id from Demis message on Edit Sample page And I validate the existence of "1" pathogen tests - And I back to the cases list from edit case + And I back to the case from Edit Sample page DE And I check if report side component in Edit Case has today date When I click on edit Report on Edit Case page And I click on Display associated external messages button from Reports side component From 3e2e153b3f8fb46426bb9127b1bf0a6a2dbbcc93 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Wed, 12 Jul 2023 08:17:08 +0200 Subject: [PATCH 024/174] qu-auto/SORQA-979 Demis - Process a Lab message that has multiple samples. Checking that ab sample id match specimen id method has been changed. --- .../services/api/demis/DemisApiService.java | 3 ++- .../application/samples/EditSampleSteps.java | 25 +++++++++++++------ .../features/sanity/web/DemisWeb.feature | 4 +-- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java index a7e1d79040c..3276f2de015 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java @@ -60,6 +60,7 @@ public class DemisApiService { private final String CONTENT_TYPE_APPLICATION_JSON = "application/json"; private JSONObject jsonObject; public static final String specimenUUID = UUID.randomUUID().toString(); + public static final String secondSpecimenUUID = UUID.randomUUID().toString(); @Inject public DemisApiService(RunningConfiguration runningConfiguration) { @@ -249,7 +250,7 @@ public String prepareLabNotificationFileWithTwoSamples( json = json.replace("\"\"", "\"" + patientLastName + "\""); json = json.replace("\"\"", "\"" + patientFirstName + "\""); json = json.replace("", specimenUUID); - json = json.replace("", UUID.randomUUID().toString()); + json = json.replace("", secondSpecimenUUID); json = json.replace("", UUID.randomUUID().toString()); json = json.replace("", UUID.randomUUID().toString()); json = json.replace("", UUID.randomUUID().toString()); diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/EditSampleSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/EditSampleSteps.java index 8afdaa5d6c0..1c4034e50f8 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/EditSampleSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/EditSampleSteps.java @@ -314,13 +314,24 @@ public EditSampleSteps( }); Then( - "^I check that lab sample id match specimen id from Demis message on Edit Sample page$", - () -> { - softly.assertEquals( - webDriverHelpers.getValueFromWebElement(LAB_SAMPLE_ID_INPUT), - DemisApiService.specimenUUID, - "Sample id is incorrect"); - softly.assertAll(); + "I check that lab sample id match {string} specimen id from Demis message on Edit Sample page", + (String specimen) -> { + switch (specimen) { + case "first": + softly.assertEquals( + webDriverHelpers.getValueFromWebElement(LAB_SAMPLE_ID_INPUT), + DemisApiService.specimenUUID, + "Sample id is incorrect"); + softly.assertAll(); + break; + case "second": + softly.assertEquals( + webDriverHelpers.getValueFromWebElement(LAB_SAMPLE_ID_INPUT), + DemisApiService.secondSpecimenUUID, + "Sample id is incorrect"); + softly.assertAll(); + break; + } }); And( diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index ae5882e394e..2306589fb96 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -517,11 +517,11 @@ Scenario: Create and send laboratory request via Demis Then I click on the first Case ID from Case Directory And I check that the number of added samples on the Edit case page is 2 And I click on edit sample icon of the 1 displayed sample on Edit Case page - And I check that lab sample id match specimen id from Demis message on Edit Sample page + And I check that lab sample id match "first" specimen id from Demis message on Edit Sample page And I validate the existence of "2" pathogen tests And I back to the case from Edit Sample page DE When I click on edit sample icon of the 2 displayed sample on Edit Case page - Then I check that lab sample id match specimen id from Demis message on Edit Sample page + Then I check that lab sample id match "second" specimen id from Demis message on Edit Sample page And I validate the existence of "1" pathogen tests And I back to the case from Edit Sample page DE And I check if report side component in Edit Case has today date From 1f64d47fd245abf30cfec196ce1b2f7d7eae78a4 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Wed, 12 Jul 2023 08:44:11 +0200 Subject: [PATCH 025/174] qu-auto/SORQA-979 Demis - Process a Lab message that has multiple samples. One additional step has been added. --- .../src/test/resources/features/sanity/web/DemisWeb.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index 2306589fb96..99da4b876fa 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -526,6 +526,7 @@ Scenario: Create and send laboratory request via Demis And I back to the case from Edit Sample page DE And I check if report side component in Edit Case has today date When I click on edit Report on Edit Case page + And I click on discard button And I click on Display associated external messages button from Reports side component And I check if external message window appears and close it Then I click on the Messages button from navbar From dfd7a987da82fdceca4efaf2cf4af4a81598ac85 Mon Sep 17 00:00:00 2001 From: Razvan Date: Wed, 12 Jul 2023 10:22:59 +0300 Subject: [PATCH 026/174] SORQA-993 : added new tests and refactored code --- .../org/sormas/e2etests/enums/UserRoles.java | 2 + .../SormasToSormasUserRights.json | 1 + .../SurvnetUserRights.json | 1 + .../entities/services/CaseService.java | 7 +- .../sormas/e2etests/steps/api/UserSteps.java | 54 +++++++- .../application/cases/CaseDirectorySteps.java | 128 +++++++++--------- .../application/cases/CreateNewCaseSteps.java | 63 +++++---- .../web/application/cases/EditCaseSteps.java | 95 +++++++------ .../application/persons/EditPersonSteps.java | 59 ++++---- .../web/application/survnet/SurvNetSteps.java | 23 ++-- .../resources/features/sanity/api/Api.feature | 40 ++++-- .../features/sanity/web/SharedCases.feature | 2 +- .../sanity/web/SharedContacts.feature | 2 +- .../features/sanity/web/Task.feature | 21 --- 14 files changed, 262 insertions(+), 236 deletions(-) create mode 100644 sormas-e2e-tests/src/main/resources/userRightsJsonTemplates/SormasToSormasUserRights.json create mode 100644 sormas-e2e-tests/src/main/resources/userRightsJsonTemplates/SurvnetUserRights.json diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/UserRoles.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/UserRoles.java index 11f33807608..74df046cf7e 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/UserRoles.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/UserRoles.java @@ -28,6 +28,8 @@ public enum UserRoles { LaboratoryOfficer("Laboratory Officer"), POESupervisor("Point of Entry Supervisor"), AdminUser("Admin User"), + SurvnetUser("Survnet"), + SormasToSormasUser("S2S"), RestUser("Rest AUTOMATION"); private final String role; diff --git a/sormas-e2e-tests/src/main/resources/userRightsJsonTemplates/SormasToSormasUserRights.json b/sormas-e2e-tests/src/main/resources/userRightsJsonTemplates/SormasToSormasUserRights.json new file mode 100644 index 00000000000..d917fa82687 --- /dev/null +++ b/sormas-e2e-tests/src/main/resources/userRightsJsonTemplates/SormasToSormasUserRights.json @@ -0,0 +1 @@ +["ACTION_CREATE","ACTION_DELETE","ACTION_EDIT","ADDITIONAL_TEST_CREATE","ADDITIONAL_TEST_DELETE","ADDITIONAL_TEST_EDIT","ADDITIONAL_TEST_VIEW","AGGREGATE_REPORT_EDIT","AGGREGATE_REPORT_EXPORT","AGGREGATE_REPORT_VIEW","CAMPAIGN_ARCHIVE","CAMPAIGN_DELETE","CAMPAIGN_EDIT","CAMPAIGN_FORM_DATA_ARCHIVE","CAMPAIGN_FORM_DATA_DELETE","CAMPAIGN_FORM_DATA_EDIT","CAMPAIGN_FORM_DATA_EXPORT","CAMPAIGN_FORM_DATA_VIEW","CAMPAIGN_VIEW","CASE_ARCHIVE","CASE_CHANGE_DISEASE","CASE_CHANGE_EPID_NUMBER","CASE_CLASSIFY","CASE_CLINICIAN_VIEW","CASE_CREATE","CASE_DELETE","CASE_EDIT","CASE_EXPORT","CASE_IMPORT","CASE_INVESTIGATE","CASE_MERGE","CASE_REFER_FROM_POE","CASE_SHARE","CASE_TRANSFER","CASE_VIEW","CLINICAL_COURSE_EDIT","CLINICAL_COURSE_VIEW","CLINICAL_VISIT_CREATE","CLINICAL_VISIT_DELETE","CLINICAL_VISIT_EDIT","CONTACT_ARCHIVE","CONTACT_CONVERT","CONTACT_CREATE","CONTACT_DELETE","CONTACT_EDIT","CONTACT_EXPORT","CONTACT_IMPORT","CONTACT_MERGE","CONTACT_REASSIGN_CASE","CONTACT_VIEW","DASHBOARD_CAMPAIGNS_VIEW","DASHBOARD_CONTACT_VIEW","DASHBOARD_CONTACT_VIEW_TRANSMISSION_CHAINS","DASHBOARD_SAMPLES_VIEW","DASHBOARD_SURVEILLANCE_VIEW","DATABASE_EXPORT_ACCESS","DEV_MODE","DOCUMENT_DELETE","DOCUMENT_TEMPLATE_MANAGEMENT","DOCUMENT_UPLOAD","DOCUMENT_VIEW","EVENTGROUP_ARCHIVE","EVENTGROUP_CREATE","EVENTGROUP_DELETE","EVENTGROUP_EDIT","EVENTGROUP_LINK","EVENTPARTICIPANT_ARCHIVE","EVENTPARTICIPANT_CREATE","EVENTPARTICIPANT_DELETE","EVENTPARTICIPANT_EDIT","EVENTPARTICIPANT_IMPORT","EVENTPARTICIPANT_VIEW","EVENT_ARCHIVE","EVENT_CREATE","EVENT_DELETE","EVENT_EDIT","EVENT_EXPORT","EVENT_IMPORT","EVENT_VIEW","EXPORT_DATA_PROTECTION_DATA","EXTERNAL_MESSAGE_DELETE","EXTERNAL_MESSAGE_PROCESS","EXTERNAL_MESSAGE_VIEW","EXTERNAL_SURVEILLANCE_DELETE","EXTERNAL_SURVEILLANCE_SHARE","IMMUNIZATION_ARCHIVE","IMMUNIZATION_CREATE","IMMUNIZATION_DELETE","IMMUNIZATION_EDIT","IMMUNIZATION_VIEW","INFRASTRUCTURE_ARCHIVE","INFRASTRUCTURE_CREATE","INFRASTRUCTURE_EDIT","INFRASTRUCTURE_EXPORT","INFRASTRUCTURE_IMPORT","INFRASTRUCTURE_VIEW","LINE_LISTING_CONFIGURE","MANAGE_EXTERNAL_SYMPTOM_JOURNAL","MANAGE_PUBLIC_EXPORT_CONFIGURATION","OUTBREAK_EDIT","OUTBREAK_VIEW","PATHOGEN_TEST_CREATE","PATHOGEN_TEST_DELETE","PATHOGEN_TEST_EDIT","PERFORM_BULK_OPERATIONS","PERFORM_BULK_OPERATIONS_CASE_SAMPLES","PERFORM_BULK_OPERATIONS_EVENT","PERFORM_BULK_OPERATIONS_EVENTPARTICIPANT","PERFORM_BULK_OPERATIONS_EXTERNAL_MESSAGES","PERFORM_BULK_OPERATIONS_PSEUDONYM","PERSON_CONTACT_DETAILS_DELETE","PERSON_DELETE","PERSON_EDIT","PERSON_EXPORT","PERSON_MERGE","PERSON_VIEW","POPULATION_MANAGE","PORT_HEALTH_INFO_EDIT","PORT_HEALTH_INFO_VIEW","PRESCRIPTION_CREATE","PRESCRIPTION_DELETE","PRESCRIPTION_EDIT","QUARANTINE_ORDER_CREATE","SAMPLE_CREATE","SAMPLE_DELETE","SAMPLE_EDIT","SAMPLE_EDIT_NOT_OWNED","SAMPLE_EXPORT","SAMPLE_TRANSFER","SAMPLE_VIEW","SEE_PERSONAL_DATA_IN_JURISDICTION","SEE_SENSITIVE_DATA_IN_JURISDICTION","SEND_MANUAL_EXTERNAL_MESSAGES","SORMAS_REST","SORMAS_TO_SORMAS_CLIENT","SORMAS_TO_SORMAS_PROCESS","SORMAS_TO_SORMAS_SHARE","SORMAS_UI","STATISTICS_ACCESS","STATISTICS_EXPORT","TASK_ARCHIVE","TASK_ASSIGN","TASK_CREATE","TASK_DELETE","TASK_EDIT","TASK_EXPORT","TASK_VIEW","THERAPY_VIEW","TRAVEL_ENTRY_ARCHIVE","TRAVEL_ENTRY_CREATE","TRAVEL_ENTRY_DELETE","TRAVEL_ENTRY_EDIT","TRAVEL_ENTRY_MANAGEMENT_ACCESS","TRAVEL_ENTRY_VIEW","TREATMENT_CREATE","TREATMENT_DELETE","TREATMENT_EDIT","USER_CREATE","USER_EDIT","USER_ROLE_DELETE","USER_ROLE_EDIT","USER_ROLE_VIEW","USER_VIEW","VISIT_CREATE","VISIT_DELETE","VISIT_EDIT","VISIT_EXPORT","WEEKLYREPORT_VIEW"] \ No newline at end of file diff --git a/sormas-e2e-tests/src/main/resources/userRightsJsonTemplates/SurvnetUserRights.json b/sormas-e2e-tests/src/main/resources/userRightsJsonTemplates/SurvnetUserRights.json new file mode 100644 index 00000000000..c4fde25677a --- /dev/null +++ b/sormas-e2e-tests/src/main/resources/userRightsJsonTemplates/SurvnetUserRights.json @@ -0,0 +1 @@ +["ACTION_CREATE","ACTION_DELETE","ACTION_EDIT","ADDITIONAL_TEST_DELETE","ADDITIONAL_TEST_VIEW","AGGREGATE_REPORT_EDIT","AGGREGATE_REPORT_EXPORT","AGGREGATE_REPORT_VIEW","CAMPAIGN_ARCHIVE","CAMPAIGN_FORM_DATA_ARCHIVE","CAMPAIGN_FORM_DATA_EDIT","CAMPAIGN_FORM_DATA_EXPORT","CAMPAIGN_FORM_DATA_VIEW","CAMPAIGN_VIEW","CASE_CHANGE_DISEASE","CASE_CHANGE_EPID_NUMBER","CASE_CLASSIFY","CASE_CREATE","CASE_DELETE","CASE_EDIT","CASE_EXPORT","CASE_INVESTIGATE","CASE_REFER_FROM_POE","CASE_SHARE","CASE_TRANSFER","CASE_VIEW","CLINICAL_COURSE_VIEW","CLINICAL_VISIT_DELETE","CONTACT_CONVERT","CONTACT_CREATE","CONTACT_DELETE","CONTACT_EDIT","CONTACT_EXPORT","CONTACT_REASSIGN_CASE","CONTACT_VIEW","DASHBOARD_CAMPAIGNS_VIEW","DASHBOARD_CONTACT_VIEW","DASHBOARD_CONTACT_VIEW_TRANSMISSION_CHAINS","DASHBOARD_SAMPLES_VIEW","DASHBOARD_SURVEILLANCE_VIEW","DATABASE_EXPORT_ACCESS","DOCUMENT_DELETE","DOCUMENT_UPLOAD","DOCUMENT_VIEW","EVENTGROUP_CREATE","EVENTGROUP_DELETE","EVENTGROUP_EDIT","EVENTGROUP_LINK","EVENTPARTICIPANT_CREATE","EVENTPARTICIPANT_DELETE","EVENTPARTICIPANT_EDIT","EVENTPARTICIPANT_IMPORT","EVENTPARTICIPANT_VIEW","EVENT_CREATE","EVENT_DELETE","EVENT_EDIT","EVENT_EXPORT","EVENT_VIEW","EXTERNAL_MESSAGE_DELETE","EXTERNAL_MESSAGE_PROCESS","EXTERNAL_MESSAGE_VIEW","EXTERNAL_SURVEILLANCE_SHARE","IMMUNIZATION_CREATE","IMMUNIZATION_DELETE","IMMUNIZATION_EDIT","IMMUNIZATION_VIEW","INFRASTRUCTURE_ARCHIVE","INFRASTRUCTURE_EXPORT","INFRASTRUCTURE_VIEW","LINE_LISTING_CONFIGURE","MANAGE_EXTERNAL_SYMPTOM_JOURNAL","MANAGE_PUBLIC_EXPORT_CONFIGURATION","OUTBREAK_EDIT","OUTBREAK_VIEW","PATHOGEN_TEST_CREATE","PATHOGEN_TEST_DELETE","PATHOGEN_TEST_EDIT","PERFORM_BULK_OPERATIONS_EXTERNAL_MESSAGES","PERSON_CONTACT_DETAILS_DELETE","PERSON_DELETE","PERSON_EDIT","PERSON_EXPORT","PERSON_MERGE","PERSON_VIEW","PORT_HEALTH_INFO_EDIT","PORT_HEALTH_INFO_VIEW","PRESCRIPTION_DELETE","QUARANTINE_ORDER_CREATE","SAMPLE_CREATE","SAMPLE_DELETE","SAMPLE_EDIT","SAMPLE_EXPORT","SAMPLE_TRANSFER","SAMPLE_VIEW","SEE_PERSONAL_DATA_IN_JURISDICTION","SEE_SENSITIVE_DATA_IN_JURISDICTION","SEND_MANUAL_EXTERNAL_MESSAGES","SORMAS_REST","SORMAS_TO_SORMAS_CLIENT","SORMAS_TO_SORMAS_PROCESS","SORMAS_TO_SORMAS_SHARE","SORMAS_UI","STATISTICS_ACCESS","STATISTICS_EXPORT","TASK_ARCHIVE","TASK_ASSIGN","TASK_CREATE","TASK_DELETE","TASK_EDIT","TASK_EXPORT","TASK_VIEW","THERAPY_VIEW","TRAVEL_ENTRY_CREATE","TRAVEL_ENTRY_DELETE","TRAVEL_ENTRY_EDIT","TRAVEL_ENTRY_MANAGEMENT_ACCESS","TRAVEL_ENTRY_VIEW","TREATMENT_DELETE","VISIT_CREATE","VISIT_DELETE","VISIT_EDIT","VISIT_EXPORT","WEEKLYREPORT_VIEW"] \ No newline at end of file diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/CaseService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/CaseService.java index 68f4b986420..ba7f219f88b 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/CaseService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/CaseService.java @@ -18,8 +18,11 @@ package org.sormas.e2etests.entities.services; +import static org.sormas.e2etests.entities.pojo.helpers.ShortUUIDGenerator.generateShortUUID; + import com.github.javafaker.Faker; import com.google.inject.Inject; +import java.time.LocalDate; import lombok.SneakyThrows; import org.sormas.e2etests.entities.pojo.web.Case; import org.sormas.e2etests.enums.CommunityValues; @@ -29,10 +32,6 @@ import org.sormas.e2etests.enums.RegionsValues; import org.sormas.e2etests.helpers.strings.ASCIIHelper; -import java.time.LocalDate; - -import static org.sormas.e2etests.entities.pojo.helpers.ShortUUIDGenerator.generateShortUUID; - public class CaseService { private final Faker faker; diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/UserSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/UserSteps.java index 05e1d6997e8..a951787f281 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/UserSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/UserSteps.java @@ -17,6 +17,8 @@ */ package org.sormas.e2etests.steps.api; +import static org.sormas.e2etests.steps.BaseSteps.locale; + import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; import cucumber.api.java8.En; @@ -24,6 +26,8 @@ import javax.inject.Inject; import org.json.simple.parser.JSONParser; import org.sormas.e2etests.entities.services.api.UserApiService; +import org.sormas.e2etests.enums.UserRoles; +import org.sormas.e2etests.envconfig.manager.RunningConfiguration; import org.sormas.e2etests.helpers.api.sormasrest.UserHelper; import org.sormas.e2etests.helpers.environmentdata.manager.EnvironmentManager; import org.sormas.e2etests.state.ApiState; @@ -37,23 +41,45 @@ public class UserSteps implements En { @Inject public UserSteps( - UserHelper userHelper, UserApiService userApiService, SoftAssert softly, ApiState apiState) { + UserHelper userHelper, + UserApiService userApiService, + SoftAssert softly, + ApiState apiState, + RunningConfiguration runningConfiguration) { When( "API:I Login into Environment", () -> { - EnvironmentManager loginIntoEnvironment = userApiService.loginIntoEnvironment(); + EnvironmentManager environmentManager = userApiService.loginIntoEnvironment(); }); When( - "API: I get response with ([^\"]*) user permission rights", + "^API: I get response with ([^\"]*) user permission rights$", (String option) -> { switch (option) { case "Admin User": - userHelper.getUserByRightsPermissions("W5QCZW-XLFVFT-E5MK66-O3SUKE7E"); // get + userHelper.getUserByRightsPermissions( + runningConfiguration + .getUserByRole(locale, UserRoles.AdminUser.getRole()) + .getUuid()); break; case "National User": - userHelper.getUserByRightsPermissions("XXFIKA-I653UK-XTLOIT-VWZYKGXY"); // get + userHelper.getUserByRightsPermissions( + runningConfiguration + .getUserByRole(locale, UserRoles.NationalUser.getRole()) + .getUuid()); + break; + case "Survnet": + userHelper.getUserByRightsPermissions( + runningConfiguration + .getUserByRole(locale, UserRoles.SurvnetUser.getRole()) + .getUuid()); + break; + case "S2S": + userHelper.getUserByRightsPermissions( + runningConfiguration + .getUserByRole(locale, UserRoles.SormasToSormasUser.getRole()) + .getUuid()); break; } responseBody = apiState.getResponse().getBody().asString(); @@ -61,7 +87,7 @@ public UserSteps( }); When( - "I prepare collection of ([^\"]*) rights based on json files", + "^I prepare collection of ([^\"]*) rights based on json files$", (String option) -> { JSONParser parser = new JSONParser(); ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); @@ -81,11 +107,25 @@ public UserSteps( "src/main/resources/userRightsJsonTemplates/NationalUserRights.json")); expectedUserRights = ow.writeValueAsString(objectToParse).replaceAll("\\s+", ""); break; + case "Survnet": + objectToParse = + parser.parse( + new FileReader( + "src/main/resources/userRightsJsonTemplates/SurvnetUserRights.json")); + expectedUserRights = ow.writeValueAsString(objectToParse).replaceAll("\\s+", ""); + break; + case "S2S": + objectToParse = + parser.parse( + new FileReader( + "src/main/resources/userRightsJsonTemplates/SormasToSormasUserRights.json")); + expectedUserRights = ow.writeValueAsString(objectToParse).replaceAll("\\s+", ""); + break; } }); When( - "I prepare collection of ([^\"]*) rights based on json files for De version", + "^I prepare collection of ([^\"]*) rights based on json files for De version$", (String option) -> { JSONParser parser = new JSONParser(); ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDirectorySteps.java index 2cca10987b7..9382445e6ca 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDirectorySteps.java @@ -18,60 +18,6 @@ package org.sormas.e2etests.steps.web.application.cases; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.javafaker.Faker; -import com.google.common.truth.Truth; -import com.opencsv.CSVParser; -import com.opencsv.CSVParserBuilder; -import com.opencsv.CSVReader; -import com.opencsv.CSVReaderBuilder; -import com.opencsv.CSVWriter; -import com.opencsv.exceptions.CsvException; -import cucumber.api.java8.En; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.openqa.selenium.By; -import org.sormas.e2etests.common.DataOperations; -import org.sormas.e2etests.entities.pojo.csv.DetailedCaseCSV; -import org.sormas.e2etests.entities.pojo.csv.DetailedCaseCSVSymptoms; -import org.sormas.e2etests.enums.CaseOutcome; -import org.sormas.e2etests.enums.DiseasesValues; -import org.sormas.e2etests.enums.DistrictsValues; -import org.sormas.e2etests.enums.FacilityCategory; -import org.sormas.e2etests.enums.FollowUpStatus; -import org.sormas.e2etests.enums.PresentCondition; -import org.sormas.e2etests.envconfig.manager.RunningConfiguration; -import org.sormas.e2etests.helpers.AssertHelpers; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.helpers.files.FilesHelper; -import org.sormas.e2etests.pages.application.cases.EditCasePage; -import org.sormas.e2etests.pages.application.contacts.EditContactPage; -import org.sormas.e2etests.state.ApiState; -import org.sormas.e2etests.steps.BaseSteps; -import org.testng.Assert; -import org.testng.asserts.SoftAssert; - -import javax.inject.Inject; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.text.DateFormatSymbols; -import java.time.LocalDate; -import java.time.ZoneId; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.concurrent.ThreadLocalRandom; -import java.util.concurrent.TimeUnit; - import static org.sormas.e2etests.entities.pojo.helpers.ShortUUIDGenerator.generateShortUUID; import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.ACTION_OKAY; import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.ACTION_RESET_POPUP; @@ -210,6 +156,59 @@ import static org.sormas.e2etests.pages.application.tasks.TaskManagementPage.BULK_DELETE_BUTTON; import static org.sormas.e2etests.steps.BaseSteps.locale; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.javafaker.Faker; +import com.google.common.truth.Truth; +import com.opencsv.CSVParser; +import com.opencsv.CSVParserBuilder; +import com.opencsv.CSVReader; +import com.opencsv.CSVReaderBuilder; +import com.opencsv.CSVWriter; +import com.opencsv.exceptions.CsvException; +import cucumber.api.java8.En; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.text.DateFormatSymbols; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; +import javax.inject.Inject; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.openqa.selenium.By; +import org.sormas.e2etests.common.DataOperations; +import org.sormas.e2etests.entities.pojo.csv.DetailedCaseCSV; +import org.sormas.e2etests.entities.pojo.csv.DetailedCaseCSVSymptoms; +import org.sormas.e2etests.enums.CaseOutcome; +import org.sormas.e2etests.enums.DiseasesValues; +import org.sormas.e2etests.enums.DistrictsValues; +import org.sormas.e2etests.enums.FacilityCategory; +import org.sormas.e2etests.enums.FollowUpStatus; +import org.sormas.e2etests.enums.PresentCondition; +import org.sormas.e2etests.envconfig.manager.RunningConfiguration; +import org.sormas.e2etests.helpers.AssertHelpers; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.helpers.files.FilesHelper; +import org.sormas.e2etests.pages.application.cases.EditCasePage; +import org.sormas.e2etests.pages.application.contacts.EditContactPage; +import org.sormas.e2etests.state.ApiState; +import org.sormas.e2etests.steps.BaseSteps; +import org.testng.Assert; +import org.testng.asserts.SoftAssert; + @Slf4j public class CaseDirectorySteps implements En { @@ -1473,16 +1472,16 @@ public CaseDirectorySteps( }); When( - "^I select (\\d+) last created UI result in grid in Case Directory for Bulk Action$", - (Integer number) -> { - webDriverHelpers.waitForPageLoadingSpinnerToDisappear(40); - for (int i = 0; i < number; i++) { - webDriverHelpers.scrollToElement( - getCheckboxByUUID(CreateNewCaseSteps.casesUUID.get(i))); - webDriverHelpers.clickOnWebElementBySelector( - getCheckboxByUUID(CreateNewCaseSteps.casesUUID.get(i))); - } - }); + "^I select (\\d+) last created UI result in grid in Case Directory for Bulk Action$", + (Integer number) -> { + webDriverHelpers.waitForPageLoadingSpinnerToDisappear(40); + for (int i = 0; i < number; i++) { + webDriverHelpers.scrollToElement( + getCheckboxByUUID(CreateNewCaseSteps.casesUUID.get(i))); + webDriverHelpers.clickOnWebElementBySelector( + getCheckboxByUUID(CreateNewCaseSteps.casesUUID.get(i))); + } + }); And( "^I click Send to reporting tool button on Case Directory page$", @@ -1492,7 +1491,6 @@ public CaseDirectorySteps( webDriverHelpers.clickOnWebElementBySelector(CONFIRM_ACTION); webDriverHelpers.waitUntilIdentifiedElementIsPresent(REPORTING_TOOL_MESSAGE); }); - } private Number getRandomNumberForBirthDateDifferentThanCreated(Number created, int min, int max) { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CreateNewCaseSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CreateNewCaseSteps.java index 498848cdf93..68b2caecb0d 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CreateNewCaseSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CreateNewCaseSteps.java @@ -18,38 +18,6 @@ package org.sormas.e2etests.steps.web.application.cases; -import com.github.javafaker.Faker; -import cucumber.api.java8.En; -import io.restassured.http.Method; -import lombok.SneakyThrows; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; -import org.sormas.e2etests.entities.pojo.api.Request; -import org.sormas.e2etests.entities.pojo.web.Case; -import org.sormas.e2etests.entities.services.CaseService; -import org.sormas.e2etests.enums.GenderValues; -import org.sormas.e2etests.helpers.RestAssuredClient; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.helpers.files.FilesHelper; -import org.sormas.e2etests.pages.application.cases.EditCasePage; -import org.sormas.e2etests.state.ApiState; -import org.sormas.e2etests.steps.BaseSteps; -import org.testng.asserts.SoftAssert; - -import javax.inject.Inject; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.time.format.TextStyle; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Random; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - import static org.sormas.e2etests.constants.api.Endpoints.CASES_PATH; import static org.sormas.e2etests.entities.pojo.helpers.ShortUUIDGenerator.generateShortUUID; import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_APPLY_FILTERS_BUTTON; @@ -162,6 +130,37 @@ import static org.sormas.e2etests.steps.web.application.contacts.CreateNewContactSteps.contact; import static org.sormas.e2etests.steps.web.application.persons.PersonDirectorySteps.personSharedForAllEntities; +import com.github.javafaker.Faker; +import cucumber.api.java8.En; +import io.restassured.http.Method; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.TextStyle; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import javax.inject.Inject; +import lombok.SneakyThrows; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.sormas.e2etests.entities.pojo.api.Request; +import org.sormas.e2etests.entities.pojo.web.Case; +import org.sormas.e2etests.entities.services.CaseService; +import org.sormas.e2etests.enums.GenderValues; +import org.sormas.e2etests.helpers.RestAssuredClient; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.helpers.files.FilesHelper; +import org.sormas.e2etests.pages.application.cases.EditCasePage; +import org.sormas.e2etests.state.ApiState; +import org.sormas.e2etests.steps.BaseSteps; +import org.testng.asserts.SoftAssert; + public class CreateNewCaseSteps implements En { private final WebDriverHelpers webDriverHelpers; diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java index 6fe4c0099c3..75622c8458d 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java @@ -18,54 +18,6 @@ package org.sormas.e2etests.steps.web.application.cases; -import cucumber.api.java8.En; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.apache.poi.xwpf.usermodel.XWPFParagraph; -import org.openqa.selenium.By; -import org.sormas.e2etests.common.DataOperations; -import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; -import org.sormas.e2etests.entities.pojo.web.Case; -import org.sormas.e2etests.entities.pojo.web.QuarantineOrder; -import org.sormas.e2etests.entities.pojo.web.Vaccination; -import org.sormas.e2etests.entities.pojo.web.epidemiologicalData.Exposure; -import org.sormas.e2etests.entities.services.CaseDocumentService; -import org.sormas.e2etests.entities.services.CaseService; -import org.sormas.e2etests.enums.CaseClassification; -import org.sormas.e2etests.enums.CaseOutcome; -import org.sormas.e2etests.enums.YesNoUnknownOptions; -import org.sormas.e2etests.enums.cases.epidemiologicalData.ExposureDetailsRole; -import org.sormas.e2etests.enums.cases.epidemiologicalData.TypeOfActivityExposure; -import org.sormas.e2etests.enums.cases.epidemiologicalData.TypeOfPlace; -import org.sormas.e2etests.envconfig.manager.RunningConfiguration; -import org.sormas.e2etests.helpers.AssertHelpers; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.helpers.files.FilesHelper; -import org.sormas.e2etests.pages.application.NavBarPage; -import org.sormas.e2etests.pages.application.cases.EditCasePage; -import org.sormas.e2etests.pages.application.contacts.EditContactPage; -import org.sormas.e2etests.pages.application.events.EditEventPage; -import org.sormas.e2etests.pages.application.immunizations.EditImmunizationPage; -import org.sormas.e2etests.state.ApiState; -import org.sormas.e2etests.steps.web.application.contacts.EditContactSteps; -import org.sormas.e2etests.steps.web.application.immunizations.EditImmunizationSteps; -import org.sormas.e2etests.steps.web.application.samples.CreateNewSampleSteps; -import org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps; -import org.testng.Assert; -import org.testng.asserts.SoftAssert; - -import javax.inject.Inject; -import java.io.FileInputStream; -import java.time.LocalDate; -import java.time.ZoneId; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.TimeUnit; - import static org.sormas.e2etests.enums.CaseOutcome.DECEASED; import static org.sormas.e2etests.enums.CaseOutcome.FACILITY_OTHER; import static org.sormas.e2etests.enums.CaseOutcome.INVESTIGATION_DISCARDED; @@ -141,6 +93,53 @@ import static org.sormas.e2etests.steps.BaseSteps.locale; import static org.sormas.e2etests.steps.web.application.contacts.ContactDirectorySteps.exposureData; +import cucumber.api.java8.En; +import java.io.FileInputStream; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; +import javax.inject.Inject; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.apache.poi.xwpf.usermodel.XWPFParagraph; +import org.openqa.selenium.By; +import org.sormas.e2etests.common.DataOperations; +import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; +import org.sormas.e2etests.entities.pojo.web.Case; +import org.sormas.e2etests.entities.pojo.web.QuarantineOrder; +import org.sormas.e2etests.entities.pojo.web.Vaccination; +import org.sormas.e2etests.entities.pojo.web.epidemiologicalData.Exposure; +import org.sormas.e2etests.entities.services.CaseDocumentService; +import org.sormas.e2etests.entities.services.CaseService; +import org.sormas.e2etests.enums.CaseClassification; +import org.sormas.e2etests.enums.CaseOutcome; +import org.sormas.e2etests.enums.YesNoUnknownOptions; +import org.sormas.e2etests.enums.cases.epidemiologicalData.ExposureDetailsRole; +import org.sormas.e2etests.enums.cases.epidemiologicalData.TypeOfActivityExposure; +import org.sormas.e2etests.enums.cases.epidemiologicalData.TypeOfPlace; +import org.sormas.e2etests.envconfig.manager.RunningConfiguration; +import org.sormas.e2etests.helpers.AssertHelpers; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.helpers.files.FilesHelper; +import org.sormas.e2etests.pages.application.NavBarPage; +import org.sormas.e2etests.pages.application.cases.EditCasePage; +import org.sormas.e2etests.pages.application.contacts.EditContactPage; +import org.sormas.e2etests.pages.application.events.EditEventPage; +import org.sormas.e2etests.pages.application.immunizations.EditImmunizationPage; +import org.sormas.e2etests.state.ApiState; +import org.sormas.e2etests.steps.web.application.contacts.EditContactSteps; +import org.sormas.e2etests.steps.web.application.immunizations.EditImmunizationSteps; +import org.sormas.e2etests.steps.web.application.samples.CreateNewSampleSteps; +import org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps; +import org.testng.Assert; +import org.testng.asserts.SoftAssert; + @Slf4j public class EditCaseSteps implements En { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/persons/EditPersonSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/persons/EditPersonSteps.java index 601d40481df..8bbc6783639 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/persons/EditPersonSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/persons/EditPersonSteps.java @@ -18,36 +18,6 @@ package org.sormas.e2etests.steps.web.application.persons; -import com.github.javafaker.Faker; -import cucumber.api.java8.En; -import org.openqa.selenium.ElementClickInterceptedException; -import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; -import org.sormas.e2etests.entities.pojo.web.Person; -import org.sormas.e2etests.entities.services.PersonService; -import org.sormas.e2etests.envconfig.manager.RunningConfiguration; -import org.sormas.e2etests.helpers.AssertHelpers; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.pages.application.contacts.EditContactPersonPage; -import org.sormas.e2etests.pages.application.persons.EditPersonPage; -import org.sormas.e2etests.state.ApiState; -import org.sormas.e2etests.steps.BaseSteps; -import org.sormas.e2etests.steps.web.application.cases.CreateNewCaseSteps; -import org.sormas.e2etests.steps.web.application.contacts.CreateNewContactSteps; -import org.sormas.e2etests.steps.web.application.contacts.EditContactPersonSteps; -import org.sormas.e2etests.steps.web.application.events.EditEventSteps; -import org.sormas.e2etests.steps.web.application.immunizations.EditImmunizationSteps; -import org.testng.Assert; -import org.testng.asserts.SoftAssert; - -import javax.inject.Inject; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.time.format.TextStyle; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.concurrent.TimeUnit; - import static org.sormas.e2etests.pages.application.cases.EpidemiologicalDataCasePage.ACTIVITY_AS_CASE_NEW_ENTRY_BUTTON_DE; import static org.sormas.e2etests.pages.application.cases.EpidemiologicalDataCasePage.EDIT_TRAVEL_ENTRY_BUTTON; import static org.sormas.e2etests.pages.application.contacts.CreateNewContactPage.SAVE_BUTTON; @@ -124,6 +94,35 @@ import static org.sormas.e2etests.steps.BaseSteps.locale; import static org.sormas.e2etests.steps.web.application.entries.CreateNewTravelEntrySteps.aTravelEntry; +import com.github.javafaker.Faker; +import cucumber.api.java8.En; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.TextStyle; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.concurrent.TimeUnit; +import javax.inject.Inject; +import org.openqa.selenium.ElementClickInterceptedException; +import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; +import org.sormas.e2etests.entities.pojo.web.Person; +import org.sormas.e2etests.entities.services.PersonService; +import org.sormas.e2etests.envconfig.manager.RunningConfiguration; +import org.sormas.e2etests.helpers.AssertHelpers; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.pages.application.contacts.EditContactPersonPage; +import org.sormas.e2etests.pages.application.persons.EditPersonPage; +import org.sormas.e2etests.state.ApiState; +import org.sormas.e2etests.steps.BaseSteps; +import org.sormas.e2etests.steps.web.application.cases.CreateNewCaseSteps; +import org.sormas.e2etests.steps.web.application.contacts.CreateNewContactSteps; +import org.sormas.e2etests.steps.web.application.contacts.EditContactPersonSteps; +import org.sormas.e2etests.steps.web.application.events.EditEventSteps; +import org.sormas.e2etests.steps.web.application.immunizations.EditImmunizationSteps; +import org.testng.Assert; +import org.testng.asserts.SoftAssert; + public class EditPersonSteps implements En { private final WebDriverHelpers webDriverHelpers; diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java index a9f3fc523ea..0a59160cd1c 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java @@ -1,6 +1,17 @@ package org.sormas.e2etests.steps.web.application.survnet; +import static org.sormas.e2etests.helpers.SchemaValidator.XMLSchemaValidator.validateXMLSchema; +import static org.sormas.e2etests.helpers.comparison.XMLComparison.compareXMLFiles; +import static org.sormas.e2etests.helpers.comparison.XMLComparison.extractDiffNodes; +import static org.sormas.e2etests.pages.application.AboutPage.SORMAS_VERSION_LINK; + import cucumber.api.java8.En; +import java.time.LocalDate; +import java.time.Period; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; +import javax.inject.Inject; import lombok.extern.slf4j.Slf4j; import org.jdom2.DataConversionException; import org.jdom2.Document; @@ -12,18 +23,6 @@ import org.sormas.e2etests.steps.web.application.persons.EditPersonSteps; import org.testng.asserts.SoftAssert; -import javax.inject.Inject; -import java.time.LocalDate; -import java.time.Period; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.List; - -import static org.sormas.e2etests.helpers.SchemaValidator.XMLSchemaValidator.validateXMLSchema; -import static org.sormas.e2etests.helpers.comparison.XMLComparison.compareXMLFiles; -import static org.sormas.e2etests.helpers.comparison.XMLComparison.extractDiffNodes; -import static org.sormas.e2etests.pages.application.AboutPage.SORMAS_VERSION_LINK; - @Slf4j public class SurvNetSteps implements En { diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/api/Api.feature b/sormas-e2e-tests/src/test/resources/features/sanity/api/Api.feature index 3691e551e2c..0848791585e 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/api/Api.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/api/Api.feature @@ -170,33 +170,43 @@ Feature: Check basic POSTs RestApi endpoints And API: I check that POST call status code is 200 @env_main @precon - Scenario: User permissions check + Scenario Outline: User permissions check Given API:I Login into Environment - Then API: I get response with Admin User user permission rights + Then API: I get response with user permission rights And API: I check that GET call status code is 200 - And I prepare collection of Admin User rights based on json files + And I prepare collection of rights based on json files And I check that user rights are complete - @env_main @precon - Scenario: User permissions check + Examples: + |user | + | Admin User | + | National User | + + @env_de @precon + Scenario Outline: User permissions check DE version Given API:I Login into Environment - Then API: I get response with National User user permission rights + Then API: I get response with user permission rights And API: I check that GET call status code is 200 - And I prepare collection of National User rights based on json files + And I prepare collection of rights based on json files for De version And I check that user rights are complete - @env_de @precon - Scenario: User permissions check for DE version + Examples: + |user | + | Admin User | + | National User | + + @env_survnet @precon + Scenario: User permissions check for Survnet User Given API:I Login into Environment - Then API: I get response with Admin User user permission rights + Then API: I get response with Survnet user permission rights And API: I check that GET call status code is 200 - And I prepare collection of Admin User rights based on json files for De version + And I prepare collection of Survnet rights based on json files And I check that user rights are complete - @env_de @precon - Scenario: User permissions check for DE version + @env_s2s_1 @precon + Scenario: User permissions check for SormasToSormas User Given API:I Login into Environment - Then API: I get response with National User user permission rights + Then API: I get response with S2S user permission rights And API: I check that GET call status code is 200 - And I prepare collection of National User rights based on json files for De version + And I prepare collection of S2S rights based on json files And I check that user rights are complete \ No newline at end of file diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedCases.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedCases.feature index 6929af127d0..261ce8c8882 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedCases.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedCases.feature @@ -1,7 +1,7 @@ @UI @Sanity @ShareCases @SharedData Feature: Sharing cases between environments tests - @tmsLink=SORQA-962 @env_s2s_1 + @tmsLink=SOR-4489 @env_s2s_1 Scenario: [S2S] Delete a shared case Given API: I create a new person with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district And API: I check that POST call status code is 200 diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedContacts.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedContacts.feature index 25e0c425a3b..d0306f95609 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedContacts.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedContacts.feature @@ -342,7 +342,7 @@ Feature: Sharing contacts between environments tests And I check if handover card contains "Geteilt von: Automation Admin" information And I check if handover card contains "shared with automated test" information - @tmsLink=SOR-982 @env_s2s_1 + @tmsLink=SOR-4483 @env_s2s_1 Scenario: Delete a contact shared in source system but not accepted in target system Given API: I create a new person with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district And API: I check that POST call status code is 200 diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Task.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Task.feature index 23a15c3a924..8df86ccbb6f 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Task.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Task.feature @@ -31,13 +31,10 @@ Feature: Tasks functionalities @env_main Scenario: Check all fields from the created Task in the Task Management table Given API: I create a new person - And API: I check that POST call status code is 200 Given API: I create a new contact - And API: I check that POST call status code is 200 And API: I create a new task - And API: I check that POST call status code is 200 Given I log in as a Surveillance Officer And I click on the Tasks button from navbar @@ -48,16 +45,12 @@ Feature: Tasks functionalities @tmsLink=SORDEV-6080 @env_main Scenario: Bulk deleting tasks in Task Directory Given API: I create a new person - And API: I check that POST call status code is 200 Given API: I create a new contact - And API: I check that POST call status code is 200 And API: I create a new task - And API: I check that POST call status code is 200 And API: I create a new task - And API: I check that POST call status code is 200 Given I log in as a Admin User And I click on the Tasks button from navbar @@ -74,16 +67,12 @@ Feature: Tasks functionalities @tmsLink=SORDEV-6080 @env_main Scenario: Bulk archiving tasks in Task Directory Given API: I create a new person - And API: I check that POST call status code is 200 Given API: I create a new contact - And API: I check that POST call status code is 200 And API: I create a new task - And API: I check that POST call status code is 200 And API: I create a new task - And API: I check that POST call status code is 200 Given I log in as a Admin User And I click on the Tasks button from navbar @@ -100,16 +89,12 @@ Feature: Tasks functionalities @tmsLink=SORDEV-6080 @env_main Scenario: Bulk editing tasks in Task Directory Given API: I create a new person - And API: I check that POST call status code is 200 Given API: I create a new contact - And API: I check that POST call status code is 200 And API: I create a new task - And API: I check that POST call status code is 200 And API: I create a new task - And API: I check that POST call status code is 200 Given I log in as a Admin User And I click on the Tasks button from navbar @@ -129,13 +114,10 @@ Feature: Tasks functionalities @tmsLink=SORDEV-9156 @env_main Scenario: Check the task observer is added Given API: I create a new person - And API: I check that POST call status code is 200 Given API: I create a new contact - And API: I check that POST call status code is 200 And API: I create a new task - And API: I check that POST call status code is 200 Given I log in as a National User And I click on the Tasks button from navbar @@ -238,13 +220,10 @@ Feature: Tasks functionalities @tmsLink=SORDEV-12438 @env_main Scenario: Test add task status Progress in task edit page Given API: I create a new person - And API: I check that POST call status code is 200 Given API: I create a new contact - And API: I check that POST call status code is 200 And API: I create a new task - And API: I check that POST call status code is 200 Given I log in as a National User And I click on the Tasks button from navbar From 0fb72d2870fdb02edb81260a59db59eb9440e1f3 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Wed, 12 Jul 2023 15:35:01 +0200 Subject: [PATCH 027/174] qu-auto/SORQA-958 Demis - Process a Lab message that has mapped 1 existing laboratory ID from Sormas. New test scenario has been added. --- ...ificationTemplateWithExistingFacility.json | 524 ++++++++++++++++++ .../services/api/demis/DemisApiService.java | 14 + .../steps/api/demisSteps/DemisSteps.java | 10 + .../features/sanity/web/DemisWeb.feature | 15 +- 4 files changed, 557 insertions(+), 6 deletions(-) create mode 100644 sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationTemplateWithExistingFacility.json diff --git a/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationTemplateWithExistingFacility.json b/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationTemplateWithExistingFacility.json new file mode 100644 index 00000000000..e9b7e8210ee --- /dev/null +++ b/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationTemplateWithExistingFacility.json @@ -0,0 +1,524 @@ +{ + "resourceType": "Bundle", + "id": "NotificationBundleLaboratory-example", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotificationBundleLaboratory" + ] + }, + "identifier": { + "system": "https://demis.rki.de/fhir/NamingSystem/NotificationBundleId", + "value": "0de84a15-3f79-439a-a33c-a5989927cf7d" + }, + "type": "document", + "timestamp": "2020-10-05T07:37:44.979+02:00", + "entry": [ + { + "fullUrl": "https://demis.rki.de/fhir/Composition/a194b5c3-a3c5-4ceb-9087-d7fd87e1ec4e", + "resource": { + "resourceType": "Composition", + "id": "a194b5c3-a3c5-4ceb-9087-d7fd87e1ec4e", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotificationLaboratory" + ] + }, + "identifier": { + "system": "https://demis.rki.de/fhir/NamingSystem/NotificationId", + "value": "" + }, + "status": "final", + "type": { + "coding": [ + { + "system": "http://loinc.org", + "code": "34782-3", + "display": "Infectious disease Note" + } + ] + }, + "category": [ + { + "coding": [ + { + "system": "http://loinc.org", + "code": "11502-2", + "display": "Laboratory report" + } + ] + } + ], + "subject": { + "reference": "Patient/61ebe359-bfdc-4613-8bf2-c5e300945f0n17" + }, + "date": "2020-09-16", + "author": [ + { + "reference": "PractitionerRole/61ebe359-bfdc-4613-8bf2-c5e300945f0n18" + } + ], + "title": "SARS-CoV-2-Erregernachweismeldung", + "relatesTo": [ + { + "code": "appends", + "targetReference": { + "type": "Composition", + "identifier": { + "system": "https://demis.rki.de/fhir/NamingSystem/NotificationId", + "value": "" + } + } + } + ], + "section": [ + { + "code": { + "coding": [ + { + "system": "http://loinc.org", + "code": "11502-2", + "display": "Laboratory report" + } + ] + }, + "entry": [ + { + "reference": "DiagnosticReport/61ebe359-bfdc-4613-8bf2-c5e300945f0n19" + } + ] + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/PractitionerRole/61ebe359-bfdc-4613-8bf2-c5e300945f0n18", + "resource": { + "resourceType": "PractitionerRole", + "id": "61ebe359-bfdc-4613-8bf2-c5e300945f0n18", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotifierRole" + ] + }, + "organization": { + "reference": "Organization/f812c7ab-f9d7-4dfd-81eb-71b2408f1c55" + } + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Organization/f812c7ab-f9d7-4dfd-81eb-71b2408f1c55", + "resource": { + "resourceType": "Organization", + "id": "f812c7ab-f9d7-4dfd-81eb-71b2408f1c55", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotifierFacility" + ] + }, + "identifier": [ + { + "system": "https://fhir.kbv.de/NamingSystem/KBV_NS_Base_BSNR", + "value": "123456789" + } + ], + "type": [ + { + "coding": [ + { + "system": "https://demis.rki.de/fhir/CodeSystem/organizationType", + "code": "laboratory", + "display": "Erregerdiagnostische Untersuchungsstelle" + } + ] + } + ], + "name": "Organization for Laboratory tests", + "telecom": [ + { + "system": "phone", + "value": "+49 30 09876543 221", + "use": "work" + }, + { + "system": "fax", + "value": "+49 30 09876543 99221", + "use": "work" + }, + { + "system": "email", + "value": "ifsg@demis-labortest.de", + "use": "work" + }, + { + "system": "url", + "value": "https://www.demis-labortest.de", + "use": "work" + } + ], + "address": [ + { + "line": [ + "Teststraße 123a Dritter Hinterhof" + ], + "city": "Teststadt", + "postalCode": "10115", + "country": "20422" + } + ], + "contact": [ + { + "name": { + "use": "official", + "family": "NachnameAnsprechpartnerIn", + "given": [ + "VornameAnsprechpartnerIn" + ] + } + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Patient/61ebe359-bfdc-4613-8bf2-c5e300945f0n17", + "resource": { + "resourceType": "Patient", + "id": "61ebe359-bfdc-4613-8bf2-c5e300945f0n17", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotifiedPerson" + ] + }, + "deceasedBoolean": "true", + "deceasedDateTime": "2021-07-29", + "name": [ + { + "use": "official", + "family": "", + "given": [ + "" + ] + } + ], + "telecom": [ + { + "extension": [ + { + "url": "https://demis.rki.de/fhir/StructureDefinition/Comment", + "valueString": "Ab 14 Uhr" + } + ], + "system": "phone", + "value": "+49 (0)12345 - 123456", + "use": "work" + } + ], + "gender": "female", + "birthDate": "1974-12-25", + "address": [ + { + "extension": [ + { + "url": "https://demis.rki.de/fhir/StructureDefinition/AddressUse", + "valueCoding": { + "system": "https://demis.rki.de/fhir/CodeSystem/addressUse", + "code": "ordinary" + } + }, + { + "url": "https://demis.rki.de/fhir/StructureDefinition/FacilityAddressNotifiedPerson", + "valueReference": { + "reference": "Organization/98cda07d-1fa7-47f6-ad79-e66de48d6078" + } + } + ] + } + ], + "contact": [ + { + "relationship": [ + { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v2-0131", + "code": "E" + } + ] + } + ], + "name": { + "use": "official", + "family": "Novak", + "given": [ + "Djokovick" + ] + } + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/DiagnosticReport/61ebe359-bfdc-4613-8bf2-c5e300945f0n19", + "resource": { + "resourceType": "DiagnosticReport", + "id": "61ebe359-bfdc-4613-8bf2-c5e300945f0n19", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/LaboratoryReportCVDP" + ] + }, + "basedOn": [ + { + "type": "ServiceRequest", + "identifier": { + "system": "https://demis.rki.de/fhir/NamingSystem/ServiceRequestId", + "value": "2022-0003456" + } + } + ], + "status": "final", + "code": { + "coding": [ + { + "system": "https://demis.rki.de/fhir/CodeSystem/notificationCategory", + "code": "cvdp", + "display": "Severe-Acute-Respiratory-Syndrome-Coronavirus-2 (SARS-CoV-2)" + } + ] + }, + "subject": { + "reference": "Patient/61ebe359-bfdc-4613-8bf2-c5e300945f0n17" + }, + "issued": "2021-03-04T11:45:33+11:00", + "result": [ + { + "reference": "Observation/" + } + ], + "conclusionCode": [ + { + "coding": [ + { + "system": "https://demis.rki.de/fhir/CodeSystem/conclusionCode", + "code": "pathogenDetected" + } + ] + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Organization/98cda07d-1fa7-47f6-ad79-e66de48d6078", + "resource": { + "resourceType": "Organization", + "id": "98cda07d-1fa7-47f6-ad79-e66de48d6078", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotifiedPersonFacility" + ] + }, + "type": [ + { + "coding": [ + { + "system": "https://demis.rki.de/fhir/CodeSystem/organizationType", + "code": "hospital" + } + ] + } + ], + "name": "Krankenhaus am See", + "telecom": [ + { + "system": "phone", + "value": "+49 (0)12345 - 123456", + "use": "work" + } + ], + "address": [ + { + "line": [ + "Kurzer Weg 15" + ], + "city": "Berlin", + "postalCode": "", + "country": "20422" + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Observation/", + "resource": { + "resourceType": "Observation", + "id": "", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/PathogenDetectionCVDP" + ] + }, + "identifier": { + "system": "https://demis.rki.de/fhir/NamingSystem/PathogenDetection", + "value": "externalID-abcd123" + }, + "status": "final", + "category": [ + { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/observation-category", + "code": "laboratory" + } + ] + } + ], + "code": { + "coding": [ + { + "system": "http://loinc.org", + "code": "94764-8", + "display": "SARS-CoV-2 (COVID-19) variant Sequencing Nom (Specimen)" + } + ] + }, + "subject": { + "reference": "Patient/61ebe359-bfdc-4613-8bf2-c5e300945f0n17" + }, + "valueString": "#AY.4", + "interpretation": [ + { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation", + "code": "POS" + } + ] + } + ], + "note": [ + { + "text": "Ich bin ein optionaler beschreibender Text ..." + } + ], + "method": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "115418004", + "display": "Viral Sequencing (procedure)" + } + ] + }, + "specimen": { + "reference": "Specimen/" + } + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Specimen/", + "resource": { + "resourceType": "Specimen", + "id": "", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/SpecimenCVDP" + ] + }, + "type": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "309164002", + "display": "Upper respiratory swab sample (specimen)" + } + ] + }, + "subject": { + "reference": "Patient/61ebe359-bfdc-4613-8bf2-c5e300945f0n17" + }, + "receivedTime": "2020-09-27T22:01:38+02:00", + "collection": { + "collector": { + "reference": "PractitionerRole/xyz2f5-8384-4191-916b-10150c780453" + }, + "collectedDateTime": "2020-08-17T10:10:00Z" + }, + "processing": [ + { + "extension": [ + { + "url": "https://demis.rki.de/fhir/StructureDefinition/TransactionID", + "valueString": "IMS-DEMIS-10001-CVDP-be8131da-9024-41a4-a53c-3ce0d6f6fe37" + } + ], + "timeDateTime": "2020-08-18T08:10:00Z" + } + ], + "note": [ + { + "text": "Die Probe gehört zu einem Ausbruch." + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/PractitionerRole/xyz2f5-8384-4191-916b-10150c780453", + "resource": { + "resourceType": "PractitionerRole", + "id": "xyz2f5-8384-4191-916b-10150c780453", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/SubmittingRole" + ] + }, + "practitioner": { + "reference": "Practitioner/42cdf5-8384-4191-916b-10150c780453" + } + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Practitioner/42cdf5-8384-4191-916b-10150c780453", + "resource": { + "resourceType": "Practitioner", + "id": "42cdf5-8384-4191-916b-10150c780453", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/SubmittingPerson" + ] + }, + "name": [ + { + "use": "official", + "family": "Mantle", + "given": [ + "Karl-Heinz" + ] + } + ], + "telecom": [ + { + "system": "phone", + "value": "+49 (0)12345 - 123456", + "use": "work" + }, + { + "system": "phone", + "value": "+49 (0)12345 - 123567", + "use": "home" + } + ], + "address": [ + { + "use": "home", + "line": [ + "Erster Weg 1" + ], + "city": "Berlin", + "state": "DE-BE", + "postalCode": "10115", + "country": "20422" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java index 3276f2de015..bd9acd9ca2f 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java @@ -258,6 +258,20 @@ public String prepareLabNotificationFileWithTwoSamples( return json; } + public String prepareLabNotificationFileWithOneExistingFacility( + String patientFirstName, String patientLastName) { + DemisData demisData = runningConfiguration.getDemisData(locale); + String file = "src/main/resources/demisJsonTemplates/labNotificationTemplateWithExistingFacility.json"; + String json = readFileAsString(file); + json = json.replace("", UUID.randomUUID().toString()); + json = json.replace("\"\"", "\"" + patientLastName + "\""); + json = json.replace("\"\"", "\"" + patientFirstName + "\""); + json = json.replace("", UUID.randomUUID().toString()); + json = json.replace("\"\"", "\"" + demisData.getPostalCode() + "\""); + json = json.replace("", UUID.randomUUID().toString()); + return json; + } + /** Delete method once we start adding tests */ @SneakyThrows public String loginRequest() { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java index 760392114d2..57616effba6 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java @@ -934,6 +934,16 @@ public DemisSteps( webDriverHelpers.clickOnWebElementBySelector(CREATE_NEW_SAMPLE_CHECKBOX); webDriverHelpers.clickOnWebElementBySelector(SAVE_SAMPLE_BUTTON); }); + + And( + "^I create and send Laboratory Notification with one existing facility$", + () -> { + patientFirstName = faker.name().firstName(); + patientLastName = faker.name().lastName(); + String json = demisApiService.prepareLabNotificationFileWithOneExistingFacility(patientFirstName, patientLastName); + + Assert.assertTrue(demisApiService.sendLabRequest(json, loginToken), "Failed to send laboratory request"); + }); } private List> getTableRowsData() { diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index 448879890ed..adf1ab9925c 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -536,7 +536,7 @@ Scenario: Create and send laboratory request via Demis @tmsLink=SORQA-958 @env_d2s @LoginKeycloak Scenario: Demis - Process a Lab message that has mapped 1 existing laboratory ID from Sormas Given API : Login to DEMIS server - And I create and send Laboratory Notification + And I create and send Laboratory Notification with one existing facility Then I click on the Messages button from navbar And I click on fetch messages button Then I filter by last created person via API in Messages Directory @@ -547,10 +547,7 @@ Scenario: Create and send laboratory request via Demis And I fill only mandatory fields to convert laboratory message into a case for DE And I click on save button in the case popup Then I check that new sample form with pathogen detection reporting process is displayed - Then I verify that labor is prefilled with "Andere Einrichtung" in New sample form while processing a DEMIS LabMessage - And I verify that labor description is prefilled with "Other Laboratory" in New sample form while processing a DEMIS LabMessage - And I fill laboratory name with "Quick laboratory" in New Sample form while processing a DEMIS LabMessage - And I fill "first" pathogen laboratory name with "Quick laboratory" in New Sample form while processing a DEMIS LabMessage + Then I verify that labor is prefilled with "Testlabor DEMIS" in New sample form while processing a DEMIS LabMessage And I click on save sample button And I click on save sample button And I click on the Cases button from navbar @@ -561,4 +558,10 @@ Scenario: Create and send laboratory request via Demis And I click on Display associated external messages button from Reports side component And I check if external message window appears and close it When I click on edit Report on Edit Case page - Then I check that Reporter Facility in Edit report form is set to "" \ No newline at end of file + Then I check that Reporter Facility in Edit report form is set to "Testlabor DEMIS (Inaktiv)" + And I click on discard button + Then I click on the Messages button from navbar + And I filter by last created person via API in Messages Directory + And I verify that status for result 1 is set to processed in Message Directory page + And I click on the eye icon next for the first fetched message + And I check if external message window appears and close it \ No newline at end of file From d63264937185b6c3b7f242bcce050b9b411cd073 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Thu, 13 Jul 2023 08:51:56 +0200 Subject: [PATCH 028/174] qu-auto/SORQA-958 Demis - Process a Lab message that has mapped 1 existing laboratory ID from Sormas. labNotificationTemplateWithExistingFacility.json has been edited. --- .../labNotificationTemplateWithExistingFacility.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationTemplateWithExistingFacility.json b/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationTemplateWithExistingFacility.json index e9b7e8210ee..fee53b1ebc4 100644 --- a/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationTemplateWithExistingFacility.json +++ b/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationTemplateWithExistingFacility.json @@ -161,7 +161,7 @@ "Teststraße 123a Dritter Hinterhof" ], "city": "Teststadt", - "postalCode": "10115", + "postalCode": "", "country": "20422" } ], @@ -514,7 +514,7 @@ ], "city": "Berlin", "state": "DE-BE", - "postalCode": "10115", + "postalCode": "", "country": "20422" } ] From 50de5bc4a300f68451b5aa3d17b5e8dea9059025 Mon Sep 17 00:00:00 2001 From: Michal Kozakiewicz Date: Thu, 13 Jul 2023 08:53:07 +0200 Subject: [PATCH 029/174] SORQA-1035 Implement "Check Vaccination and Vaccination Status of case when sending from SORMAS to Meldesoftware" - added new test, enum VaccineNameValues, new builder for vaccinaction --- .../immunizations/VaccineNameValues.java | 47 +++++++ .../entities/services/VaccinationService.java | 15 +++ .../web/application/survnet/SurvNetSteps.java | 122 +++++++++++++++--- .../CreateNewVaccinationSteps.java | 16 +++ .../features/sanity/web/Survnet.feature | 23 +++- 5 files changed, 204 insertions(+), 19 deletions(-) create mode 100644 sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/immunizations/VaccineNameValues.java diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/immunizations/VaccineNameValues.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/immunizations/VaccineNameValues.java new file mode 100644 index 00000000000..cf41654cc20 --- /dev/null +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/immunizations/VaccineNameValues.java @@ -0,0 +1,47 @@ +/* + * SORMAS® - Surveillance Outbreak Response Management & Analysis System + * Copyright © 2016-2023 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sormas.e2etests.enums.immunizations; + +import java.util.Random; +import lombok.Getter; + +@Getter +public enum VaccineNameValues { + COMIRNATY("Comirnaty (COVID-19-mRNA Impfstoff)"), + MRNA_BIVALENT_BA_1_BIONTECH_PFIZER("mRNA/bivalent BA.1 (BioNTech/Pfizer)"), + MRNA_BIVALENT_BA_4_5_BIONTECH_PFIZER("mRNA/bivalent BA.4/5 (BioNTech/Pfizer)"), + COVID_19_Impfstoff_Moderna("COVID-19 Impfstoff Moderna (mRNA-Impfstoff)"), + MRNA_BIVALENT_BA_1_MODERNA("mRNA/bivalent BA.1 (Moderna)"), + MRNA_BIVALENT_BA_4_5_MODERNA("mRNA/bivalent BA.4/5 (Moderna)"), + INAKTIVIERT("inaktiviert (Valneva)"), + NVX_COV2373_COVID19("NVX-CoV2373 COVID-19 Impfstoff (Novavax)"), + PROTEINBASIERT("proteinbasiert, rekombinant (Novavax)"); + + private final String vaccineName; + + private static Random random = new Random(); + + VaccineNameValues(String vaccineName) { + this.vaccineName = vaccineName; + } + + public static String getRandomVaccineName() { + return String.valueOf(VaccineNameValues.values()[random.nextInt(values().length)].vaccineName); + } +} \ No newline at end of file diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/VaccinationService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/VaccinationService.java index 6880a9c22fe..951a3b27700 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/VaccinationService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/VaccinationService.java @@ -22,6 +22,7 @@ import com.google.inject.Inject; import java.time.LocalDate; import org.sormas.e2etests.entities.pojo.web.Vaccination; +import org.sormas.e2etests.enums.immunizations.VaccineNameValues; public class VaccinationService { private final Faker faker; @@ -46,6 +47,20 @@ public Vaccination buildGeneratedVaccinationDE() { .build(); } + public Vaccination buildGeneratedVaccinationSurvnetDE() { + return Vaccination.builder() + .vaccinationDate(LocalDate.now().minusDays(1)) + .vaccineName(VaccineNameValues.getRandomVaccineName()) + .vaccineType(faker.medical().medicineName()) + .vaccinationInfoSource("Impfpass") + .vaccineDose(String.valueOf(faker.number().numberBetween(0, 3))) + .inn(String.valueOf(faker.idNumber())) + .uniiCode(String.valueOf(faker.idNumber())) + .batchNumber(String.valueOf(faker.idNumber())) + .atcCode(String.valueOf(faker.idNumber())) + .build(); + } + public Vaccination buildGeneratedVaccinationWithSpecificVaccinationDateDE( LocalDate vaccinationDate) { return Vaccination.builder() diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java index d108cf3e565..8120d3c2c88 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java @@ -5,6 +5,13 @@ import static org.sormas.e2etests.helpers.comparison.XMLComparison.extractDiffNodes; import static org.sormas.e2etests.pages.application.AboutPage.SORMAS_VERSION_LINK; +import static org.sormas.e2etests.helpers.SchemaValidator.XMLSchemaValidator.validateXMLSchema; +import static org.sormas.e2etests.helpers.comparison.XMLComparison.compareXMLFiles; +import static org.sormas.e2etests.helpers.comparison.XMLComparison.extractDiffNodes; +import static org.sormas.e2etests.pages.application.AboutPage.SORMAS_VERSION_LINK; +import static org.sormas.e2etests.steps.web.application.cases.EditCaseSteps.externalUUID; +import static org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps.vaccination; + import cucumber.api.java8.En; import java.time.LocalDate; import java.time.Period; @@ -22,7 +29,6 @@ import org.sormas.e2etests.helpers.parsers.XMLParser; import org.sormas.e2etests.pages.application.NavBarPage; import org.sormas.e2etests.steps.web.application.cases.CreateNewCaseSteps; -import org.sormas.e2etests.steps.web.application.cases.EditCaseSteps; import org.sormas.e2etests.steps.web.application.events.EditEventSteps; import org.sormas.e2etests.steps.web.application.persons.EditPersonSteps; import org.testng.asserts.SoftAssert; @@ -47,28 +53,77 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { switch (typeOfDate) { case "date of report": - LocalDate dateOfReport = getReportingDate(singleXmlFile, 0); - softly.assertEquals(dateOfReport, expectedDate, "Date of report is incorrect!"); - softly.assertAll(); + LocalDate dateOfReport = + getDateValueFromSpecificFieldByName(singleXmlFile, "ReportingDate"); + softly.assertEquals(dateOfReport, expectedDate, "Date of report is incorrect!"); + softly.assertAll(); break; case "change at date": - LocalDate changeAtDate = getChangedAt(singleXmlFile, 0); - softly.assertEquals(changeAtDate, expectedDate, "Change at date is incorrect!"); - softly.assertAll(); + LocalDate changeAtDate = + getDateValueFromSpecificFieldByName(singleXmlFile, "ChangedAt"); + softly.assertEquals(changeAtDate, expectedDate, "Change at date is incorrect!"); + softly.assertAll(); break; case "created at date": - LocalDate createdAt = getCreatedAt(singleXmlFile); - softly.assertEquals(createdAt, expectedDate, "Created at date is incorrect!"); - softly.assertAll(); + LocalDate createdAtDate = + getDateValueFromSpecificFieldByName(singleXmlFile, "CreatedAt"); + softly.assertEquals(createdAtDate, expectedDate, "Created at date is incorrect!"); + softly.assertAll(); break; case "tracked at date": - LocalDate trackedAt = getTrackedAt(singleXmlFile, 0); - softly.assertEquals(trackedAt, expectedDate, "Tracked at date is incorrect!"); + LocalDate trackedAtDate = + getDateValueFromSpecificFieldByName(singleXmlFile, "TrackedAt"); + softly.assertEquals(trackedAtDate, expectedDate, "Tracked at date is incorrect!"); + softly.assertAll(); + break; + case "vaccination date": + LocalDate vaccinationDate = + getDateValueFromSpecificFieldByName(singleXmlFile, "VaccinationDate"); + softly.assertEquals(vaccinationDate, expectedDate, "Vaccination date is incorrect!"); softly.assertAll(); break; } }); + Then( + "I check if Vaccine name in SORMAS generated XML file is correct", + () -> { + String vaccineNamefromXml = getValueFromSpecificFieldByName(singleXmlFile, "Vaccine"); + String expectedVaccineName = vaccination.getVaccineName(); + String vaccineName = null; + switch (vaccineNamefromXml) { + case "201": + vaccineName = "Comirnaty (COVID-19-mRNA Impfstoff)"; + break; + case "211": + vaccineName = "mRNA/bivalent BA.1 (BioNTech/Pfizer)"; + break; + case "215": + vaccineName = "mRNA/bivalent BA.4/5 (BioNTech/Pfizer)"; + break; + case "202": + vaccineName = "COVID-19 Impfstoff Moderna (mRNA-Impfstoff)"; + break; + case "212": + vaccineName = "mRNA/bivalent BA.1 (Moderna)"; + break; + case "216": + vaccineName = "mRNA/bivalent BA.4/5 (Moderna)"; + break; + case "213": + vaccineName = "inaktiviert (Valneva)"; + break; + case "206": + vaccineName = "NVX-CoV2373 COVID-19 Impfstoff (Novavax)"; + break; + case "214": + vaccineName = "proteinbasiert, rekombinant (Novavax)"; + break; + } + softly.assertEquals(vaccineName, expectedVaccineName, "Vaccine name is incorrect!"); + softly.assertAll(); + }); + And( "I check if sex in SORMAS generated single XML file is correct", () -> { @@ -96,7 +151,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { compareXMLFiles( "src/main/resources/survnetXMLTemplates/controlXml.xml", "/srv/dockerdata/jenkins_new/sormas-files/case_" - + EditCaseSteps.externalUUID.get(0).substring(1, 37) + + externalUUID.get(0).substring(1, 37) + ".xml"); List nodes = extractDiffNodes(diffs, "/[Transport][^\\s]+"); @@ -131,7 +186,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { validateXMLSchema( "src/main/resources/survnetXMLTemplates/xmlSchema.xsd", "/srv/dockerdata/jenkins_new/sormas-files/case_" - + EditCaseSteps.externalUUID.get(0).substring(1, 37) + + externalUUID.get(0).substring(1, 37) + ".xml"), "Generated XML file does not match an example XSD schema"); softly.assertAll(); @@ -171,7 +226,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { singleXmlFile = XMLParser.getDocument( "/srv/dockerdata/jenkins_new/sormas-files/case_" - + EditCaseSteps.externalUUID.get(0).substring(1, 37) + + externalUUID.get(0).substring(1, 37) + ".xml"); }); @@ -181,7 +236,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { bulkXmlFile = XMLParser.getDocument( "/srv/dockerdata/jenkins_new/sormas-files/bulk_case_" - + EditCaseSteps.externalUUID.get(0).substring(1, 37) + + externalUUID.get(0).substring(1, 37) + ".xml"); }); @@ -245,7 +300,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { singleXmlFile = XMLParser.getDocument( "/srv/dockerdata/jenkins_new/sormas-files/event_" - + EditEventSteps.externalEventUUID.get(0).substring(1,37) + + EditEventSteps.externalEventUUID.get(0).substring(1, 37) + ".xml"); }); @@ -254,10 +309,20 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { () -> { softly.assertEquals( getGuidRecord(singleXmlFile, 0), - EditEventSteps.externalEventUUID.get(0).substring(1,37), + EditEventSteps.externalEventUUID.get(0).substring(1, 37), "External event UUID is incorrect!"); softly.assertAll(); }); + + And( + "^I check if case external UUID in SORMAS generated XML file is correct$", + () -> { + softly.assertEquals( + getGuidRecord(singleXmlFile, 0), + externalUUID.get(0).substring(1, 37), + "External case UUID is incorrect!"); + softly.assertAll(); + }); } private LocalDate getReportingDate(Document xmlFile, int caseNumber) { @@ -405,4 +470,25 @@ private String getValueFromSpecificFieldByName(Document xmlFile, String name) { } return value; } + + private LocalDate getDateValueFromSpecificFieldByName(Document xmlFile, String name) { + Element rootElement = xmlFile.getRootElement(); + Namespace ns = rootElement.getNamespace(); + String value = null; + + Element field = + xmlFile.getRootElement().getChildren().get(0).getChildren("Field", ns).stream() + .filter(e -> e.getAttributeValue("Name").equals(name)) + .findFirst() + .orElse(null); + + if (field != null) { + Attribute valueAttribute = field.getAttribute("Value"); + if (valueAttribute != null) { + value = valueAttribute.getValue().substring(0, 10); + ; + } + } + return LocalDate.parse(value, DATE_FORMATTER); + } } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/vaccination/CreateNewVaccinationSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/vaccination/CreateNewVaccinationSteps.java index f7a6693a5e1..b081d075a34 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/vaccination/CreateNewVaccinationSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/vaccination/CreateNewVaccinationSteps.java @@ -44,6 +44,7 @@ import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Locale; +import java.util.concurrent.TimeUnit; import javax.inject.Inject; import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; import org.sormas.e2etests.entities.pojo.web.Vaccination; @@ -79,6 +80,21 @@ public CreateNewVaccinationSteps( fillBatchNumber(vaccination.getBatchNumber()); fillAtcCode(vaccination.getAtcCode()); }); + + When( + "I fill new vaccination data in new Vaccination form in Survnet for DE", + () -> { + vaccination = vaccinationService.buildGeneratedVaccinationSurvnetDE(); + fillVaccinationDate(vaccination.getVaccinationDate(), Locale.GERMAN); + selectVaccineName(vaccination.getVaccineName()); + fillVaccineType(vaccination.getVaccineType()); + selectVaccinationInfoSource(vaccination.getVaccinationInfoSource()); + fillVaccineDose(vaccination.getVaccineDose()); + fillInn(vaccination.getInn()); + fillUniiCode(vaccination.getUniiCode()); + fillBatchNumber(vaccination.getBatchNumber()); + fillAtcCode(vaccination.getAtcCode()); + }); When( "I fill new duplicate vaccination data in new Vaccination form for DE without vaccination date and name", () -> { diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature index e74b626c521..598a95d51a5 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature @@ -117,4 +117,25 @@ Feature: Survnet tests And I open SORMAS generated XML file for event single message And I check if event external UUID in SORMAS generated XML file is correct And I check if "created at date" in SORMAS generated XML file is correct - And I check if "change at date" in SORMAS generated XML file is correct \ No newline at end of file + And I check if "change at date" in SORMAS generated XML file is correct + + @tmsLink=SORQA-1035 + Scenario: Check Vaccination and Vaccination Status of case when sending from SORMAS to Meldesoftware + Given I log in as a Survnet + When I click on the Cases button from navbar + And I click on the NEW CASE button + And I create a new case with mandatory data only for Survnet DE + And I navigate to case tab + Then I click NEW VACCINATION button for DE + And I fill new vaccination data in new Vaccination form in Survnet for DE + And I set the vaccination date 14 days before the date of symptom in displayed vaccination form + And I click SAVE button in new Vaccination form + Then I check if Vaccination Status is set to "Geimpft" on Edit Case page + And I click on Send to reporting tool button on Edit Case page + And I collect case external UUID from Edit Case page + Then I wait 50 seconds for system reaction + And I open SORMAS generated XML file for single case message + And I check if case external UUID in SORMAS generated XML file is correct + And I check if "date of report" in SORMAS generated XML file is correct + And I check if "vaccination date" in SORMAS generated XML file is correct + And I check if Vaccine name in SORMAS generated XML file is correct \ No newline at end of file From 7f04057bf224516efac2d0296442ab87f7b603e7 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Thu, 13 Jul 2023 09:12:07 +0200 Subject: [PATCH 030/174] qu-auto/SORQA-958 Demis - Process a Lab message that has mapped 1 existing laboratory ID from Sormas. Missing login step has been added. --- .../features/sanity/web/DemisWeb.feature | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index adf1ab9925c..89d55b70c76 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -536,10 +536,11 @@ Scenario: Create and send laboratory request via Demis @tmsLink=SORQA-958 @env_d2s @LoginKeycloak Scenario: Demis - Process a Lab message that has mapped 1 existing laboratory ID from Sormas Given API : Login to DEMIS server - And I create and send Laboratory Notification with one existing facility - Then I click on the Messages button from navbar + When I create and send Laboratory Notification with one existing facility + And I log in as a Admin User + And I click on the Messages button from navbar And I click on fetch messages button - Then I filter by last created person via API in Messages Directory + And I filter by last created person via API in Messages Directory And I click on Verarbeiten button in Messages Directory And I pick a new person in Pick or create person popup during case creation for DE And I choose create new case in Pick or create entry form for DE @@ -547,20 +548,20 @@ Scenario: Create and send laboratory request via Demis And I fill only mandatory fields to convert laboratory message into a case for DE And I click on save button in the case popup Then I check that new sample form with pathogen detection reporting process is displayed - Then I verify that labor is prefilled with "Testlabor DEMIS" in New sample form while processing a DEMIS LabMessage - And I click on save sample button + And I verify that labor is prefilled with "Testlabor DEMIS" in New sample form while processing a DEMIS LabMessage + When I click on save sample button And I click on save sample button And I click on the Cases button from navbar And I search the case by last created person via Demis message - Then I click on the first Case ID from Case Directory + And I click on the first Case ID from Case Directory And I click on Display associated lab messages button from Samples side component - And I check if external message window appears and close it + Then I check if external message window appears and close it And I click on Display associated external messages button from Reports side component And I check if external message window appears and close it When I click on edit Report on Edit Case page Then I check that Reporter Facility in Edit report form is set to "Testlabor DEMIS (Inaktiv)" And I click on discard button - Then I click on the Messages button from navbar + And I click on the Messages button from navbar And I filter by last created person via API in Messages Directory And I verify that status for result 1 is set to processed in Message Directory page And I click on the eye icon next for the first fetched message From 9377a9c717c8df587c3aa27897caf75382df12bb Mon Sep 17 00:00:00 2001 From: Michal Kozakiewicz Date: Thu, 13 Jul 2023 09:38:49 +0200 Subject: [PATCH 031/174] SORQA-1028 Implement "Symptoms in case when sending from SORMAS to Meldesoftware" - fixes --- .../steps/web/application/survnet/SurvNetSteps.java | 6 ------ .../src/test/resources/features/sanity/web/Survnet.feature | 2 -- 2 files changed, 8 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java index 4e1a25c8f1e..6d501e4a2b2 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java @@ -156,9 +156,6 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { symptom + " checkbox value is incorrect!"); softly.assertAll(); break; - case "Chills Sweats": - System.out.print("Not mapped to xml !!!"); - break; case "Acute Respiratory Distress Syndrome": String acuteRespiratoryDistressSyndromeOptionFromXml = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0394"); @@ -242,9 +239,6 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { symptom + " checkbox value is incorrect!"); softly.assertAll(); break; - case "Oxygen Saturation Lower94": - System.out.print("Not mapped to xml !!!"); - break; case "Rapid Breathing": String rapidBreathingOptionFromXml = getValueFromSpecificFieldByName(singleXmlFile, "Symptom0418"); diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature index 10f6f79ce6f..0e374c94452 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature @@ -178,14 +178,12 @@ Feature: Survnet tests And I check if "Headache" SYMPTOM in SORMAS generated single XML file is correct And I check if "Muscle Pain" SYMPTOM in SORMAS generated single XML file is correct And I check if "Feeling Ill" SYMPTOM in SORMAS generated single XML file is correct - And I check if "Chills Sweats" SYMPTOM in SORMAS generated single XML file is correct And I check if "Acute Respiratory Distress Syndrome" SYMPTOM in SORMAS generated single XML file is correct And I check if "Sore Throat" SYMPTOM in SORMAS generated single XML file is correct And I check if "Cough" SYMPTOM in SORMAS generated single XML file is correct And I check if "Runny Nose" SYMPTOM in SORMAS generated single XML file is correct And I check if "Pneumonia Clinical Or Radiologic" SYMPTOM in SORMAS generated single XML file is correct And I check if "Respiratory Disease Ventilation" SYMPTOM in SORMAS generated single XML file is correct - And I check if "Oxygen Saturation Lower94" SYMPTOM in SORMAS generated single XML file is correct And I check if "Rapid Breathing" SYMPTOM in SORMAS generated single XML file is correct And I check if "Difficulty Breathing" SYMPTOM in SORMAS generated single XML file is correct And I check if "Fast Heart Rate" SYMPTOM in SORMAS generated single XML file is correct From 506fc67d95a2dbb41ba4208ffb5c290f1d5cfeba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jul 2023 17:32:08 +0000 Subject: [PATCH 032/174] Bump libphonenumber from 8.13.14 to 8.13.16 in /sormas-base Bumps [libphonenumber](https://github.com/google/libphonenumber) from 8.13.14 to 8.13.16. - [Release notes](https://github.com/google/libphonenumber/releases) - [Changelog](https://github.com/google/libphonenumber/blob/master/making-metadata-changes.md) - [Commits](https://github.com/google/libphonenumber/compare/v8.13.14...v8.13.16) --- updated-dependencies: - dependency-name: com.googlecode.libphonenumber:libphonenumber dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index 068a7cb76d8..d8d1ee483a0 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -431,7 +431,7 @@ com.googlecode.libphonenumber libphonenumber - 8.13.14 + 8.13.16 provided From c812ee9db83fef3fe55e86e88fc45fd8e4068e22 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Jul 2023 17:59:52 +0000 Subject: [PATCH 033/174] Bump h2 from 2.1.214 to 2.2.220 in /sormas-base Bumps [h2](https://github.com/h2database/h2database) from 2.1.214 to 2.2.220. - [Release notes](https://github.com/h2database/h2database/releases) - [Commits](https://github.com/h2database/h2database/compare/version-2.1.214...version-2.2.220) --- updated-dependencies: - dependency-name: com.h2database:h2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index d8d1ee483a0..521c541ad73 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -1250,7 +1250,7 @@ com.h2database h2 - 2.1.214 + 2.2.220 test From 125f312258c81f80d2a42004b43be73308ef5097 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jul 2023 18:00:05 +0000 Subject: [PATCH 034/174] Bump checker-qual from 3.35.0 to 3.36.0 in /sormas-base Bumps [checker-qual](https://github.com/typetools/checker-framework) from 3.35.0 to 3.36.0. - [Release notes](https://github.com/typetools/checker-framework/releases) - [Changelog](https://github.com/typetools/checker-framework/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/typetools/checker-framework/compare/checker-framework-3.35.0...checker-framework-3.36.0) --- updated-dependencies: - dependency-name: org.checkerframework:checker-qual dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index 521c541ad73..af60eb94384 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -753,7 +753,7 @@ org.checkerframework checker-qual - 3.35.0 + 3.36.0 provided From 839bdd0cede148b4319bcfec3fbe9c999052efe5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Jun 2023 18:06:05 +0000 Subject: [PATCH 035/174] Bump google-http-client-gson from 1.43.2 to 1.43.3 in /sormas-base Bumps [google-http-client-gson](https://github.com/googleapis/google-http-java-client) from 1.43.2 to 1.43.3. - [Release notes](https://github.com/googleapis/google-http-java-client/releases) - [Changelog](https://github.com/googleapis/google-http-java-client/blob/main/CHANGELOG.md) - [Commits](https://github.com/googleapis/google-http-java-client/compare/v1.43.2...v1.43.3) --- updated-dependencies: - dependency-name: com.google.http-client:google-http-client-gson dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index af60eb94384..1f574566c54 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -417,7 +417,7 @@ com.google.http-client google-http-client-gson - 1.43.2 + 1.43.3 provided From ee4d612823a66be16f5892eb4cede5a26ad3f815 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 13:50:55 +0000 Subject: [PATCH 036/174] Bump commons-io from 2.11.0 to 2.13.0 in /sormas-base Bumps commons-io from 2.11.0 to 2.13.0. --- updated-dependencies: - dependency-name: commons-io:commons-io dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index 1f574566c54..ab2cd279322 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -506,7 +506,7 @@ commons-io commons-io - 2.11.0 + 2.13.0 provided From 974a4e17ae6d0e039eb374a4af41c0eab1e5efb7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jul 2023 17:13:10 +0000 Subject: [PATCH 037/174] Bump cargo-maven3-plugin from 1.10.7 to 1.10.8 in /sormas-base Bumps cargo-maven3-plugin from 1.10.7 to 1.10.8. --- updated-dependencies: - dependency-name: org.codehaus.cargo:cargo-maven3-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index ab2cd279322..042e7c2f6d0 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -1683,7 +1683,7 @@ org.codehaus.cargo cargo-maven3-plugin - 1.10.7 + 1.10.8 org.codehaus.mojo From 749ab6db52259d1049a87d9dae5f6444a2623cff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Jun 2023 18:05:27 +0000 Subject: [PATCH 038/174] Bump commons-codec from 1.15 to 1.16.0 in /sormas-base Bumps [commons-codec](https://github.com/apache/commons-codec) from 1.15 to 1.16.0. - [Changelog](https://github.com/apache/commons-codec/blob/master/RELEASE-NOTES.txt) - [Commits](https://github.com/apache/commons-codec/compare/rel/commons-codec-1.15...rel/commons-codec-1.16.0) --- updated-dependencies: - dependency-name: commons-codec:commons-codec dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index 042e7c2f6d0..a71062da1e1 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -494,7 +494,7 @@ commons-codec commons-codec - 1.15 + 1.16.0 provided From 57ddd89c9434f92c3bda70df59976c52960aac1a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Jun 2023 18:04:23 +0000 Subject: [PATCH 039/174] Bump google-http-client from 1.43.2 to 1.43.3 in /sormas-base Bumps [google-http-client](https://github.com/googleapis/google-http-java-client) from 1.43.2 to 1.43.3. - [Release notes](https://github.com/googleapis/google-http-java-client/releases) - [Changelog](https://github.com/googleapis/google-http-java-client/blob/main/CHANGELOG.md) - [Commits](https://github.com/googleapis/google-http-java-client/compare/v1.43.2...v1.43.3) --- updated-dependencies: - dependency-name: com.google.http-client:google-http-client dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index a71062da1e1..db609a81a38 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -411,7 +411,7 @@ com.google.http-client google-http-client - 1.43.2 + 1.43.3 provided From 1460341e68daec072fe2f3c353dd2c2e96140867 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 21:34:46 +0000 Subject: [PATCH 040/174] Bump apache-tika.version from 2.6.0 to 2.8.0 in /sormas-base Bumps `apache-tika.version` from 2.6.0 to 2.8.0. Updates `tika-core` from 2.6.0 to 2.8.0 - [Changelog](https://github.com/apache/tika/blob/main/CHANGES.txt) - [Commits](https://github.com/apache/tika/compare/2.6.0...2.8.0) Updates `tika-parsers-standard-package` from 2.6.0 to 2.8.0 --- updated-dependencies: - dependency-name: org.apache.tika:tika-core dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: org.apache.tika:tika-parsers-standard-package dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index db609a81a38..59784da36c0 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -46,7 +46,7 @@ 5.9.3 2.2 5.2.0 - 2.6.0 + 2.8.0 0.4.2 From 56350a995a8ae7abf002f4917f275fccb272e97c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 21:36:56 +0000 Subject: [PATCH 041/174] Bump org.mockito:mockito-core from 5.3.0 to 5.4.0 in /sormas-app Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.3.0 to 5.4.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.3.0...v5.4.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- sormas-app/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-app/app/build.gradle b/sormas-app/app/build.gradle index 899af119bd3..e23229365f7 100644 --- a/sormas-app/app/build.gradle +++ b/sormas-app/app/build.gradle @@ -145,7 +145,7 @@ dependencies { testImplementation 'org.hamcrest:hamcrest-core:2.2' testImplementation 'org.hamcrest:hamcrest-library:2.2' testImplementation 'org.robolectric:robolectric:4.10.3' - testImplementation 'org.mockito:mockito-core:5.3.0' + testImplementation 'org.mockito:mockito-core:5.4.0' androidTestImplementation 'androidx.annotation:annotation:1.5.0' androidTestImplementation 'androidx.test:runner:1.5.2' androidTestImplementation 'androidx.test:rules:1.5.0' From 5f5a6b6495ab0797bbc31cc90b3d11732698a221 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 21:36:51 +0000 Subject: [PATCH 042/174] Bump com.fasterxml.jackson.core:jackson-annotations in /sormas-app Bumps [com.fasterxml.jackson.core:jackson-annotations](https://github.com/FasterXML/jackson) from 2.14.2 to 2.15.2. - [Commits](https://github.com/FasterXML/jackson/commits) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-annotations dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- sormas-app/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-app/app/build.gradle b/sormas-app/app/build.gradle index e23229365f7..7be06f6d5bc 100644 --- a/sormas-app/app/build.gradle +++ b/sormas-app/app/build.gradle @@ -130,7 +130,7 @@ dependencies { implementation 'io.reactivex:rxandroid:1.2.1' implementation 'io.reactivex:rxjava:1.3.8' implementation 'com.fasterxml.jackson.core:jackson-core:2.15.2' - implementation 'com.fasterxml.jackson.core:jackson-annotations:2.14.2' + implementation 'com.fasterxml.jackson.core:jackson-annotations:2.15.2' implementation 'androidx.lifecycle:lifecycle-viewmodel:2.6.1' implementation 'androidx.paging:paging-runtime:3.1.1' implementation 'androidx.work:work-runtime-ktx:2.8.1' From d2557bfbb9d0439f64b646906816ad66e2cfa57e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 21:37:06 +0000 Subject: [PATCH 043/174] Bump com.google.firebase:firebase-crashlytics-gradle from 2.9.5 to 2.9.6 in /sormas-app Dependabot couldn't find the original pull request head commit, 313e1d825232e4d56aa68e6245786ad0e5dd1aec. --- sormas-app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-app/build.gradle b/sormas-app/build.gradle index 326360e0719..0005219f11c 100644 --- a/sormas-app/build.gradle +++ b/sormas-app/build.gradle @@ -9,7 +9,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:8.0.0' classpath 'com.google.gms:google-services:4.3.15' - classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.5' + classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.6' classpath 'com.google.firebase:perf-plugin:1.4.2' classpath 'org.jacoco:org.jacoco.core:0.8.10' classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:4.0.0.2929' From 265ebbf6c4aab2788e64e4af78c97b5e4f5c4b5e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Jun 2023 18:14:41 +0000 Subject: [PATCH 044/174] Bump commons-codec:commons-codec from 1.15 to 1.16.0 in /sormas-app Bumps [commons-codec:commons-codec](https://github.com/apache/commons-codec) from 1.15 to 1.16.0. - [Changelog](https://github.com/apache/commons-codec/blob/master/RELEASE-NOTES.txt) - [Commits](https://github.com/apache/commons-codec/compare/rel/commons-codec-1.15...rel/commons-codec-1.16.0) --- updated-dependencies: - dependency-name: commons-codec:commons-codec dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- sormas-app/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-app/app/build.gradle b/sormas-app/app/build.gradle index 7be06f6d5bc..3df62dcb0c0 100644 --- a/sormas-app/app/build.gradle +++ b/sormas-app/app/build.gradle @@ -113,7 +113,7 @@ dependencies { implementation 'com.google.guava:guava:32.0.1-jre' implementation 'com.opencsv:opencsv:5.7.1' implementation 'commons-beanutils:commons-beanutils:1.9.4' - implementation 'commons-codec:commons-codec:1.15' + implementation 'commons-codec:commons-codec:1.16.0' implementation 'commons-collections:commons-collections:3.2.2' implementation 'commons-logging:commons-logging:1.2' implementation 'org.apache.commons:commons-collections4:4.4' From 4f11a9d14c37b164cea8e761c02de0f3281a76fc Mon Sep 17 00:00:00 2001 From: sormas-vitagroup Date: Thu, 13 Jul 2023 09:59:06 +0000 Subject: [PATCH 045/174] [GitHub Actions] Update openAPI spec files --- sormas-rest/swagger.json | 24 ++++++++++++++++++++++++ sormas-rest/swagger.yaml | 16 ++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/sormas-rest/swagger.json b/sormas-rest/swagger.json index 6a68d4d93a8..88a21fca015 100644 --- a/sormas-rest/swagger.json +++ b/sormas-rest/swagger.json @@ -12722,8 +12722,20 @@ }, { "type" : "object", "properties" : { + "classificationCriteria" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/ClassificationCriteriaDto" + } + }, "criteriaName" : { "type" : "string" + }, + "subCriteria" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/ClassificationCriteriaDto" + } } } } ] @@ -12827,12 +12839,24 @@ }, { "type" : "object", "properties" : { + "classificationCriteria" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/ClassificationCriteriaDto" + } + }, "criteriaName" : { "type" : "string" }, "requiredAmount" : { "type" : "integer", "format" : "int32" + }, + "subCriteria" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/ClassificationCriteriaDto" + } } } } ] diff --git a/sormas-rest/swagger.yaml b/sormas-rest/swagger.yaml index 1a3718edc6d..843a2fb04bb 100644 --- a/sormas-rest/swagger.yaml +++ b/sormas-rest/swagger.yaml @@ -10673,8 +10673,16 @@ components: - $ref: '#/components/schemas/ClassificationCriteriaDto' - type: object properties: + classificationCriteria: + type: array + items: + $ref: '#/components/schemas/ClassificationCriteriaDto' criteriaName: type: string + subCriteria: + type: array + items: + $ref: '#/components/schemas/ClassificationCriteriaDto' ClassificationPathogenTestCriteriaDto: type: object allOf: @@ -10805,11 +10813,19 @@ components: - $ref: '#/components/schemas/ClassificationCriteriaDto' - type: object properties: + classificationCriteria: + type: array + items: + $ref: '#/components/schemas/ClassificationCriteriaDto' criteriaName: type: string requiredAmount: type: integer format: int32 + subCriteria: + type: array + items: + $ref: '#/components/schemas/ClassificationCriteriaDto' ClinicalCourseDto: type: object properties: From a933aaf7d589b3467f264c90f32abed33e91cfb7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 21:37:22 +0000 Subject: [PATCH 046/174] Bump com.google.android.material:material in /sormas-app Bumps [com.google.android.material:material](https://github.com/material-components/material-components-android) from 1.8.0 to 1.9.0. - [Release notes](https://github.com/material-components/material-components-android/releases) - [Commits](https://github.com/material-components/material-components-android/compare/1.8.0...1.9.0) --- updated-dependencies: - dependency-name: com.google.android.material:material dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- sormas-app/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-app/app/build.gradle b/sormas-app/app/build.gradle index 3df62dcb0c0..1ce320b144a 100644 --- a/sormas-app/app/build.gradle +++ b/sormas-app/app/build.gradle @@ -97,7 +97,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation platform('com.google.firebase:firebase-bom:32.1.1') implementation 'androidx.appcompat:appcompat:1.6.1' - implementation 'com.google.android.material:material:1.8.0' + implementation 'com.google.android.material:material:1.9.0' implementation 'androidx.percentlayout:percentlayout:1.0.0' implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' From 7182034002f0b17de959ebfada447c48a66b451e Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Thu, 13 Jul 2023 13:03:37 +0300 Subject: [PATCH 047/174] #12256 - [Users] Loop of loading when updating the user role of a specific user --- .../sormas/backend/caze/CaseFacadeEjb.java | 53 +++++++++++-- .../sormas/backend/user/UserFacadeEjb.java | 77 ++++++++++++++++++- 2 files changed, 121 insertions(+), 9 deletions(-) diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseFacadeEjb.java index 1ae1d9edbe5..930b316858a 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseFacadeEjb.java @@ -196,6 +196,7 @@ import de.symeda.sormas.api.therapy.TherapyReferenceDto; import de.symeda.sormas.api.therapy.TreatmentCriteria; import de.symeda.sormas.api.therapy.TreatmentDto; +import de.symeda.sormas.api.user.JurisdictionLevel; import de.symeda.sormas.api.user.NotificationType; import de.symeda.sormas.api.user.UserReferenceDto; import de.symeda.sormas.api.user.UserRight; @@ -2353,7 +2354,19 @@ private void sendConfirmedCaseNotificationsForEvents(Case caze) { @RightsAllowed(UserRight._CASE_EDIT) public void setCaseResponsible(Case caze) { - if (featureConfigurationFacade.isPropertyValueTrue(FeatureType.CASE_SURVEILANCE, FeatureTypeProperty.AUTOMATIC_RESPONSIBILITY_ASSIGNMENT)) { + setCaseResponsible(caze, false, null, null, null); + } + + @RightsAllowed(UserRight._CASE_EDIT) + public void setCaseResponsible( + Case caze, + boolean neededFeatureAlreadyChecked, + List possibleUsersForReplacementSurvOfficerBasedOnResponsibleDistrict, + List possibleUsersForReplacementSurvOfficerBasedOnDistrict, + Set possibleUsersForReplacementFacilityUsers) { + if (neededFeatureAlreadyChecked + || featureConfigurationFacade + .isPropertyValueTrue(FeatureType.CASE_SURVEILANCE, FeatureTypeProperty.AUTOMATIC_RESPONSIBILITY_ASSIGNMENT)) { District reportingUserDistrict = caze.getReportingUser().getDistrict(); if (userRoleService.hasUserRight(caze.getReportingUser().getUserRoles(), UserRight.CASE_RESPONSIBLE) @@ -2362,20 +2375,46 @@ public void setCaseResponsible(Case caze) { || reportingUserDistrict.equals(caze.getDistrict()))) { caze.setSurveillanceOfficer(caze.getReportingUser()); } else { - List hospitalUsers = caze.getHealthFacility() != null && FacilityType.HOSPITAL.equals(caze.getHealthFacility().getType()) - ? userService.getFacilityUsersOfHospital(caze.getHealthFacility()) - : new ArrayList<>(); + List hospitalUsers; + if (possibleUsersForReplacementFacilityUsers == null) { + hospitalUsers = caze.getHealthFacility() != null && FacilityType.HOSPITAL.equals(caze.getHealthFacility().getType()) + ? userService.getFacilityUsersOfHospital(caze.getHealthFacility()) + : new ArrayList<>(); + } else { + hospitalUsers = possibleUsersForReplacementFacilityUsers.stream() + .filter( + user -> user.getHealthFacility().equals(caze.getHealthFacility()) + && user.getJurisdictionLevel().equals(JurisdictionLevel.HEALTH_FACILITY)) + .collect(Collectors.toList()); + } Random rand = new Random(); + if (!hospitalUsers.isEmpty()) { caze.setSurveillanceOfficer(hospitalUsers.get(rand.nextInt(hospitalUsers.size())).getAssociatedOfficer()); - } else { + } + + else { User survOff = null; if (caze.getResponsibleDistrict() != null) { - survOff = getRandomDistrictCaseResponsible(caze.getResponsibleDistrict()); + if (possibleUsersForReplacementSurvOfficerBasedOnResponsibleDistrict == null) { + survOff = getRandomDistrictCaseResponsible(caze.getResponsibleDistrict()); + } else if (!possibleUsersForReplacementSurvOfficerBasedOnResponsibleDistrict.isEmpty()) { + List collect = possibleUsersForReplacementSurvOfficerBasedOnResponsibleDistrict.stream() + .filter(user -> caze.getResponsibleDistrict().equals(user.getDistrict())) + .collect(Collectors.toList()); + survOff = collect.size() > 0 ? collect.get(new Random().nextInt(collect.size())) : null; + } } if (survOff == null && caze.getDistrict() != null) { - survOff = getRandomDistrictCaseResponsible(caze.getDistrict()); + if (possibleUsersForReplacementSurvOfficerBasedOnDistrict == null) { + survOff = getRandomDistrictCaseResponsible(caze.getDistrict()); + } else if (!possibleUsersForReplacementSurvOfficerBasedOnDistrict.isEmpty()) { + List collect = possibleUsersForReplacementSurvOfficerBasedOnDistrict.stream() + .filter(user -> caze.getDistrict().equals(user.getDistrict())) + .collect(Collectors.toList()); + survOff = collect.size() > 0 ? collect.get(new Random().nextInt(collect.size())) : null; + } } caze.setSurveillanceOfficer(survOff); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserFacadeEjb.java index 5aa69d2afde..583a79f83af 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserFacadeEjb.java @@ -25,6 +25,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -52,6 +53,7 @@ import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; import de.symeda.sormas.api.Disease; import de.symeda.sormas.api.EntityDto; @@ -66,6 +68,7 @@ import de.symeda.sormas.api.i18n.Validations; import de.symeda.sormas.api.infrastructure.InfrastructureHelper; import de.symeda.sormas.api.infrastructure.district.DistrictReferenceDto; +import de.symeda.sormas.api.infrastructure.facility.FacilityDto; import de.symeda.sormas.api.infrastructure.region.RegionReferenceDto; import de.symeda.sormas.api.task.TaskContext; import de.symeda.sormas.api.task.TaskContextIndexCriteria; @@ -839,10 +842,19 @@ public void removeUserAsSurveillanceAndContactOfficer(String userUuid) { caseQuery.where(cb.equal(surveillanceOfficerJoin.get(AbstractDomainObject.UUID), userUuid)); List cases = em.createQuery(caseQuery).getResultList(); + + List possibleUsersBasedOnCasesResponsibleDistrict = getPossibleUsersBasedOnCasesResponsibleDistrict(cases); + List possibleUsersBasedOnCasesDistrict = getPossibleUsersBasedOnCasesDistrict(cases); + Set possibleUsersBasedOnCasesFacility = getPossibleUsersBasedOnCasesFacility(cases); + cases.forEach(c -> { c.setSurveillanceOfficer(null); - caseFacade.setCaseResponsible(c); - caseService.ensurePersisted(c); + caseFacade.setCaseResponsible( + c, + true, + possibleUsersBasedOnCasesResponsibleDistrict, + possibleUsersBasedOnCasesDistrict, + possibleUsersBasedOnCasesFacility); caseFacade.reassignTasksOfCase(c, true); }); @@ -858,6 +870,67 @@ public void removeUserAsSurveillanceAndContactOfficer(String userUuid) { }); } + private List getPossibleUsersBasedOnCasesResponsibleDistrict(List cases) { + List responsibleDistrictsUuidsAmongCases = cases.stream() + .map(Case::getResponsibleDistrict) + .collect(Collectors.toSet()) + .stream() + .filter(Objects::nonNull) + .collect(Collectors.toSet()) + .stream() + .map(District::getUuid) + .collect(Collectors.toList()); + + List possibleUserForReplacement = getUsersFromCasesByDistricts(responsibleDistrictsUuidsAmongCases); + + return possibleUserForReplacement; + } + + private List getPossibleUsersBasedOnCasesDistrict(List cases) { + List districtsUuidsAmongCases = cases.stream() + .map(Case::getDistrict) + .collect(Collectors.toSet()) + .stream() + .filter(Objects::nonNull) + .collect(Collectors.toSet()) + .stream() + .map(District::getUuid) + .collect(Collectors.toList()); + + List possibleUserForReplacement = getUsersFromCasesByDistricts(districtsUuidsAmongCases); + + return possibleUserForReplacement; + } + + @NotNull + private List getUsersFromCasesByDistricts(List districtsUuidsAmongCases) { + List possibleUserForReplacement = userService + .getUserReferencesByJurisdictions( + null, + districtsUuidsAmongCases, + null, + Collections.singletonList(JurisdictionLevel.DISTRICT), + Arrays.asList(UserRight.CASE_RESPONSIBLE)) + .stream() + .map(userReference -> userService.getByUuid(userReference.getUuid())) + .collect(Collectors.toList()); + return possibleUserForReplacement; + } + + private Set getPossibleUsersBasedOnCasesFacility(List cases) { + Set possibleFacilities = cases.stream().map(Case::getHealthFacility).collect(Collectors.toSet()); + + Set possibleUsersForAvailableFacilities = new HashSet<>(); + + possibleFacilities.forEach(facility -> { + if (!facility.getUuid().equals(FacilityDto.NONE_FACILITY_UUID) && !facility.getUuid().equals(FacilityDto.OTHER_FACILITY_UUID)) { + possibleUsersForAvailableFacilities.addAll(userService.getFacilityUsersOfHospital(facility)); + } + }); + + return possibleUsersForAvailableFacilities; + } + @Override @RightsAllowed({ UserRight._USER_CREATE, From 5c37829eb469cdf0d664b466ee01ebac13c15674 Mon Sep 17 00:00:00 2001 From: Michal Kozakiewicz Date: Thu, 13 Jul 2023 12:33:58 +0200 Subject: [PATCH 048/174] SORQA-1028 Implement "Symptoms in case when sending from SORMAS to Meldesoftware" - fixes 2 --- .../src/test/resources/features/sanity/web/Survnet.feature | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature index 0e374c94452..183ca44acd6 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature @@ -89,7 +89,7 @@ Feature: Survnet tests And I check if external person uuid for all 2 cases in SORMAS generated bult XML file is correct And I check if "date of report" for all 2 cases in SORMAS generated bulk XML file is correct - @tmsLink=SORQA-1029 + @tmsLink=SORQA-1028 Scenario: Symptoms in case when sending from SORMAS to Meldesoftware with YES checkbox option for Survnet DE Given I log in as a Survnet When I click on the Cases button from navbar @@ -125,7 +125,7 @@ Feature: Survnet tests And I check if "Other Non Hemorrhagic Symptoms" SYMPTOM in SORMAS generated single XML file is correct And I check if "Onset Of Disease" SYMPTOM in SORMAS generated single XML file is correct - @tmsLink=SORQA-1029 + @tmsLink=SORQA-1028 Scenario: Symptoms in case when sending from SORMAS to Meldesoftware with NO checkbox option for Survnet DE Given I log in as a Survnet When I click on the Cases button from navbar @@ -160,7 +160,7 @@ Feature: Survnet tests And I check if "Loss OfTaste" SYMPTOM in SORMAS generated single XML file is correct And I check if "Other Non Hemorrhagic Symptoms" SYMPTOM in SORMAS generated single XML file is correct - @tmsLink=SORQA-1029 + @tmsLink=SORQA-1028 Scenario: Symptoms in case when sending from SORMAS to Meldesoftware with UNKNOWN checkbox option for Survnet DE Given I log in as a Survnet When I click on the Cases button from navbar From 94ade6890d963352b838ed5f036b22b8653c89a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Jul 2023 10:06:49 +0000 Subject: [PATCH 049/174] Bump aquasecurity/trivy-action from 0.9.2 to 0.11.2 Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.9.2 to 0.11.2. - [Release notes](https://github.com/aquasecurity/trivy-action/releases) - [Commits](https://github.com/aquasecurity/trivy-action/compare/0.9.2...0.11.2) --- updated-dependencies: - dependency-name: aquasecurity/trivy-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e0d62c7ef8f..b4047c4170e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -97,7 +97,7 @@ jobs: uses: github/codeql-action/analyze@v2 - name: Run Trivy vulnerability scanner in repo mode - uses: aquasecurity/trivy-action@0.9.2 + uses: aquasecurity/trivy-action@0.11.2 with: scan-type: 'fs' ignore-unfixed: true From eecebff86d5957dc4a04e0120b48306c98513d81 Mon Sep 17 00:00:00 2001 From: Michal Kozakiewicz Date: Thu, 13 Jul 2023 14:17:22 +0200 Subject: [PATCH 050/174] Implement "Check Vaccination and Vaccination Status of case when sending from SORMAS to Meldesoftware" - actualized --- .../src/test/resources/features/sanity/web/Survnet.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature index 14226748742..bbfb428ce14 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature @@ -242,4 +242,4 @@ Feature: Survnet tests And I check if case external UUID in SORMAS generated XML file is correct And I check if "date of report" in SORMAS generated XML file is correct And I check if "vaccination date" in SORMAS generated XML file is correct - And I check if Vaccine name in SORMAS generated XML file is correct \ No newline at end of file + And I check if Vaccine name in SORMAS generated XML file is correct From 2f981ecf84ba384a217e7c317a1dea346957a360 Mon Sep 17 00:00:00 2001 From: Michal Kozakiewicz Date: Thu, 13 Jul 2023 16:06:51 +0200 Subject: [PATCH 051/174] SORQA-1035 Implement "Check Vaccination and Vaccination Status of case when sending from SORMAS to Meldesoftware" - refactoring --- .../web/application/survnet/SurvNetSteps.java | 48 +++++++------------ 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java index 358c1b005ae..44a5326faec 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java @@ -1,21 +1,11 @@ package org.sormas.e2etests.steps.web.application.survnet; -import static org.sormas.e2etests.helpers.SchemaValidator.XMLSchemaValidator.validateXMLSchema; -import static org.sormas.e2etests.helpers.comparison.XMLComparison.compareXMLFiles; -import static org.sormas.e2etests.helpers.comparison.XMLComparison.extractDiffNodes; -import static org.sormas.e2etests.pages.application.AboutPage.SORMAS_VERSION_LINK; -import static org.sormas.e2etests.steps.web.application.cases.SymptomsTabSteps.symptoms; - -import static org.sormas.e2etests.helpers.SchemaValidator.XMLSchemaValidator.validateXMLSchema; -import static org.sormas.e2etests.helpers.comparison.XMLComparison.compareXMLFiles; -import static org.sormas.e2etests.helpers.comparison.XMLComparison.extractDiffNodes; -import static org.sormas.e2etests.pages.application.AboutPage.SORMAS_VERSION_LINK; - import static org.sormas.e2etests.helpers.SchemaValidator.XMLSchemaValidator.validateXMLSchema; import static org.sormas.e2etests.helpers.comparison.XMLComparison.compareXMLFiles; import static org.sormas.e2etests.helpers.comparison.XMLComparison.extractDiffNodes; import static org.sormas.e2etests.pages.application.AboutPage.SORMAS_VERSION_LINK; import static org.sormas.e2etests.steps.web.application.cases.EditCaseSteps.externalUUID; +import static org.sormas.e2etests.steps.web.application.cases.SymptomsTabSteps.symptoms; import static org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps.vaccination; import cucumber.api.java8.En; @@ -59,33 +49,31 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { switch (typeOfDate) { case "date of report": - LocalDate dateOfReport = - getDateValueFromSpecificFieldByName(singleXmlFile, "ReportingDate"); - softly.assertEquals(dateOfReport, expectedDate, "Date of report is incorrect!"); - softly.assertAll(); + LocalDate dateOfReport = getReportingDate(singleXmlFile, 0); + softly.assertEquals(dateOfReport, expectedDate, "Date of report is incorrect!"); + softly.assertAll(); break; case "change at date": - LocalDate changeAtDate = - getDateValueFromSpecificFieldByName(singleXmlFile, "ChangedAt"); - softly.assertEquals(changeAtDate, expectedDate, "Change at date is incorrect!"); - softly.assertAll(); + LocalDate changeAtDate = getChangedAt(singleXmlFile, 0); + softly.assertEquals(changeAtDate, expectedDate, "Change at date is incorrect!"); + softly.assertAll(); break; case "created at date": - LocalDate createdAtDate = - getDateValueFromSpecificFieldByName(singleXmlFile, "CreatedAt"); - softly.assertEquals(createdAtDate, expectedDate, "Created at date is incorrect!"); - softly.assertAll(); + LocalDate createdAt = getCreatedAt(singleXmlFile); + softly.assertEquals(createdAt, expectedDate, "Created at date is incorrect!"); + softly.assertAll(); break; case "tracked at date": - LocalDate trackedAtDate = - getDateValueFromSpecificFieldByName(singleXmlFile, "TrackedAt"); - softly.assertEquals(trackedAtDate, expectedDate, "Tracked at date is incorrect!"); - softly.assertAll(); + LocalDate trackedAt = getTrackedAt(singleXmlFile, 0); + softly.assertEquals(trackedAt, expectedDate, "Tracked at date is incorrect!"); + softly.assertAll(); break; case "vaccination date": LocalDate vaccinationDate = - getDateValueFromSpecificFieldByName(singleXmlFile, "VaccinationDate"); - softly.assertEquals(vaccinationDate, expectedDate, "Vaccination date is incorrect!"); + getDateValueFromSpecificChildrenFieldByName(singleXmlFile, "VaccinationDate"); + LocalDate expectedVaccinationDate = vaccination.getVaccinationDate(); + softly.assertEquals( + vaccinationDate, expectedVaccinationDate, "Vaccination date is incorrect!"); softly.assertAll(); break; } @@ -755,7 +743,7 @@ private String getValueFromSpecificFieldByName(Document xmlFile, String name) { return value; } - private LocalDate getDateValueFromSpecificFieldByName(Document xmlFile, String name) { + private LocalDate getDateValueFromSpecificChildrenFieldByName(Document xmlFile, String name) { Element rootElement = xmlFile.getRootElement(); Namespace ns = rootElement.getNamespace(); String value = null; From 78a8fd6423326e379df1abfce4243f052961f1a5 Mon Sep 17 00:00:00 2001 From: Michal Kozakiewicz Date: Fri, 14 Jul 2023 08:45:39 +0200 Subject: [PATCH 052/174] SORQA-1035 Implement "Check Vaccination and Vaccination Status of case when sending from SORMAS to Meldesoftware" - refactoring no.2 --- .../steps/web/application/survnet/SurvNetSteps.java | 9 +++++---- .../vaccination/CreateNewVaccinationSteps.java | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java index 44a5326faec..8dfbd3f7fb5 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java @@ -6,7 +6,7 @@ import static org.sormas.e2etests.pages.application.AboutPage.SORMAS_VERSION_LINK; import static org.sormas.e2etests.steps.web.application.cases.EditCaseSteps.externalUUID; import static org.sormas.e2etests.steps.web.application.cases.SymptomsTabSteps.symptoms; -import static org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps.vaccination; +import static org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps.*; import cucumber.api.java8.En; import java.time.LocalDate; @@ -70,7 +70,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { break; case "vaccination date": LocalDate vaccinationDate = - getDateValueFromSpecificChildrenFieldByName(singleXmlFile, "VaccinationDate"); + getDateValueFromSpecificChildNodeFieldByName(singleXmlFile, "VaccinationDate"); LocalDate expectedVaccinationDate = vaccination.getVaccinationDate(); softly.assertEquals( vaccinationDate, expectedVaccinationDate, "Vaccination date is incorrect!"); @@ -83,7 +83,8 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { "I check if Vaccine name in SORMAS generated XML file is correct", () -> { String vaccineNamefromXml = getValueFromSpecificFieldByName(singleXmlFile, "Vaccine"); - String expectedVaccineName = vaccination.getVaccineName(); + String expectedVaccineName = randomVaccinationName; + String vaccineName = null; switch (vaccineNamefromXml) { case "201": @@ -743,7 +744,7 @@ private String getValueFromSpecificFieldByName(Document xmlFile, String name) { return value; } - private LocalDate getDateValueFromSpecificChildrenFieldByName(Document xmlFile, String name) { + private LocalDate getDateValueFromSpecificChildNodeFieldByName(Document xmlFile, String name) { Element rootElement = xmlFile.getRootElement(); Namespace ns = rootElement.getNamespace(); String value = null; diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/vaccination/CreateNewVaccinationSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/vaccination/CreateNewVaccinationSteps.java index b081d075a34..39d003e2eee 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/vaccination/CreateNewVaccinationSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/vaccination/CreateNewVaccinationSteps.java @@ -44,7 +44,6 @@ import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Locale; -import java.util.concurrent.TimeUnit; import javax.inject.Inject; import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; import org.sormas.e2etests.entities.pojo.web.Vaccination; @@ -59,6 +58,7 @@ public class CreateNewVaccinationSteps implements En { public static Vaccination duplicatedVacinationDe; public static Vaccination collectedVaccination; public static final DateTimeFormatter formatterDE = DateTimeFormatter.ofPattern("dd.MM.yyyy"); + public static String randomVaccinationName; @Inject public CreateNewVaccinationSteps( @@ -94,6 +94,7 @@ public CreateNewVaccinationSteps( fillUniiCode(vaccination.getUniiCode()); fillBatchNumber(vaccination.getBatchNumber()); fillAtcCode(vaccination.getAtcCode()); + randomVaccinationName = vaccination.getVaccineName(); }); When( "I fill new duplicate vaccination data in new Vaccination form for DE without vaccination date and name", From 677eecc92a28154bf44a553104513fc88f7f1a17 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Jul 2023 17:51:07 +0000 Subject: [PATCH 053/174] Bump docx4j.version from 8.3.8 to 8.3.9 in /sormas-base Bumps `docx4j.version` from 8.3.8 to 8.3.9. Updates `docx4j-docx-anon` from 8.3.8 to 8.3.9 - [Changelog](https://github.com/plutext/docx4j/blob/VERSION_11_4_8/CHANGELOG.md) - [Commits](https://github.com/plutext/docx4j/commits) Updates `docx4j-JAXB-ReferenceImpl` from 8.3.8 to 8.3.9 - [Changelog](https://github.com/plutext/docx4j/blob/VERSION_11_4_8/CHANGELOG.md) - [Commits](https://github.com/plutext/docx4j/commits) --- updated-dependencies: - dependency-name: org.docx4j:docx4j-docx-anon dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.docx4j:docx4j-JAXB-ReferenceImpl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index 59784da36c0..c055937ca1c 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -41,7 +41,7 @@ 5.0.7.Final 1.8.22 2.0.4 - 8.3.8 + 8.3.9 1.0.1 5.9.3 2.2 From cb91292cf405e2fe97cb9f212a5cc20729e1942b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 14:18:25 +0000 Subject: [PATCH 054/174] Bump postgresql from 1.17.6 to 1.18.3 in /sormas-base Bumps [postgresql](https://github.com/testcontainers/testcontainers-java) from 1.17.6 to 1.18.3. - [Release notes](https://github.com/testcontainers/testcontainers-java/releases) - [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md) - [Commits](https://github.com/testcontainers/testcontainers-java/compare/1.17.6...1.18.3) --- updated-dependencies: - dependency-name: org.testcontainers:postgresql dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index c055937ca1c..ff04f33df1f 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -1259,7 +1259,7 @@ org.testcontainers postgresql - 1.17.6 + 1.18.3 test From d451dbd1c3260acb5b3beea2e0f6551d82e145de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 21:37:44 +0000 Subject: [PATCH 055/174] Bump logback.version from 1.3.5 to 1.4.8 in /sormas-base Bumps `logback.version` from 1.3.5 to 1.4.8. Updates `logback-core` from 1.3.5 to 1.4.8 - [Commits](https://github.com/qos-ch/logback/compare/v_1.3.5...v_1.4.8) Updates `logback-classic` from 1.3.5 to 1.4.8 - [Commits](https://github.com/qos-ch/logback/compare/v_1.3.5...v_1.4.8) --- updated-dependencies: - dependency-name: ch.qos.logback:logback-core dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: ch.qos.logback:logback-classic dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index ff04f33df1f..ece96889f1f 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -29,7 +29,7 @@ 2.0.7 - 1.3.5 + 1.4.8 TODO: Remove bootstrap.js in widgetset 8.14.3 ${vaadin.version} From c2cde70629216adb63501ae0709f0dce1f8c4e26 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 14:24:00 +0000 Subject: [PATCH 056/174] Bump json-path from 2.7.0 to 2.8.0 in /sormas-base Bumps [json-path](https://github.com/jayway/JsonPath) from 2.7.0 to 2.8.0. - [Release notes](https://github.com/jayway/JsonPath/releases) - [Changelog](https://github.com/json-path/JsonPath/blob/master/changelog.md) - [Commits](https://github.com/jayway/JsonPath/compare/json-path-2.7.0...json-path-2.8.0) --- updated-dependencies: - dependency-name: com.jayway.jsonpath:json-path dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index ece96889f1f..33f23697cdd 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -445,7 +445,7 @@ com.jayway.jsonpath json-path - 2.7.0 + 2.8.0 provided From 1e4deed0ec4a10cc04c8a55df2d81f2053610e20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Jul 2023 17:40:23 +0000 Subject: [PATCH 057/174] Bump github/super-linter from 4 to 5 Bumps [github/super-linter](https://github.com/github/super-linter) from 4 to 5. - [Changelog](https://github.com/github/super-linter/blob/main/docs/release-process.md) - [Commits](https://github.com/github/super-linter/compare/v4...v5) --- updated-dependencies: - dependency-name: github/super-linter dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/linter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 28a50f7b762..1a7e140796f 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -46,7 +46,7 @@ jobs: # Run Linter against code base # ################################ - name: Lint Code Base - uses: github/super-linter/slim@v4 + uses: github/super-linter/slim@v5 env: DEFAULT_BRANCH: development GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 76c72aeaf24659423dceca9895931efd62355d3e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Jul 2023 17:40:20 +0000 Subject: [PATCH 058/174] Bump actions/checkout from 1 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 1 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v1...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/github_pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github_pages.yml b/.github/workflows/github_pages.yml index e01a57231ff..35dad6b8bc9 100644 --- a/.github/workflows/github_pages.yml +++ b/.github/workflows/github_pages.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout development - uses: actions/checkout@v1 + uses: actions/checkout@v3 - name: Copy files run: | cp README.md docs/index.md From 5a9d1e0e37d9b5d22fe175fb7a4ec92e82fa2d67 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Jul 2023 17:16:12 +0000 Subject: [PATCH 059/174] Bump com.google.firebase:firebase-crashlytics-gradle in /sormas-app Bumps com.google.firebase:firebase-crashlytics-gradle from 2.9.6 to 2.9.7. --- updated-dependencies: - dependency-name: com.google.firebase:firebase-crashlytics-gradle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- sormas-app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-app/build.gradle b/sormas-app/build.gradle index 0005219f11c..2e40ddb9921 100644 --- a/sormas-app/build.gradle +++ b/sormas-app/build.gradle @@ -9,7 +9,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:8.0.0' classpath 'com.google.gms:google-services:4.3.15' - classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.6' + classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.7' classpath 'com.google.firebase:perf-plugin:1.4.2' classpath 'org.jacoco:org.jacoco.core:0.8.10' classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:4.0.0.2929' From 1643a58656630e5bfb3208cddb3d09219ffac596 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 21:36:53 +0000 Subject: [PATCH 060/174] Bump org.sonarsource.scanner.gradle:sonarqube-gradle-plugin Bumps [org.sonarsource.scanner.gradle:sonarqube-gradle-plugin](https://github.com/SonarSource/sonar-scanner-gradle) from 4.0.0.2929 to 4.2.1.3168. - [Release notes](https://github.com/SonarSource/sonar-scanner-gradle/releases) - [Commits](https://github.com/SonarSource/sonar-scanner-gradle/commits) --- updated-dependencies: - dependency-name: org.sonarsource.scanner.gradle:sonarqube-gradle-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- sormas-app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-app/build.gradle b/sormas-app/build.gradle index 2e40ddb9921..361ef05df6c 100644 --- a/sormas-app/build.gradle +++ b/sormas-app/build.gradle @@ -12,7 +12,7 @@ buildscript { classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.7' classpath 'com.google.firebase:perf-plugin:1.4.2' classpath 'org.jacoco:org.jacoco.core:0.8.10' - classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:4.0.0.2929' + classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:4.2.1.3168' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files From da5c6118a8535231a35178557d2db702943f7422 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 14:14:39 +0000 Subject: [PATCH 061/174] Bump annotations from 17.0.0 to 24.0.1 in /sormas-base Bumps [annotations](https://github.com/JetBrains/java-annotations) from 17.0.0 to 24.0.1. - [Release notes](https://github.com/JetBrains/java-annotations/releases) - [Changelog](https://github.com/JetBrains/java-annotations/blob/master/CHANGELOG.md) - [Commits](https://github.com/JetBrains/java-annotations/compare/17.0.0...24.0.1) --- updated-dependencies: - dependency-name: org.jetbrains:annotations dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index 33f23697cdd..2d15632b9c9 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -958,7 +958,7 @@ org.jetbrains annotations - 17.0.0 + 24.0.1 provided From c7de8eaf9de8f14bc8c6e0d818550f555ca0f0b4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jul 2023 17:32:55 +0000 Subject: [PATCH 062/174] Bump org.hl7.fhir.r4 from 5.6.88 to 6.0.21 in /sormas-base Bumps org.hl7.fhir.r4 from 5.6.88 to 6.0.21. --- updated-dependencies: - dependency-name: ca.uhn.hapi.fhir:org.hl7.fhir.r4 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index 2d15632b9c9..9a0a93c715d 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -1181,7 +1181,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.r4 - 5.6.88 + 6.0.21 compile From 32c9af7986c414bf18292258615acf13cb9fcb5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Jul 2023 17:30:30 +0000 Subject: [PATCH 063/174] Bump kotlin-stdlib.version from 1.8.22 to 1.9.0 in /sormas-base Bumps `kotlin-stdlib.version` from 1.8.22 to 1.9.0. Updates `kotlin-stdlib` from 1.8.22 to 1.9.0 - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v1.8.22...v1.9.0) Updates `kotlin-stdlib-common` from 1.8.22 to 1.9.0 - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v1.8.22...v1.9.0) Updates `kotlin-stdlib-jdk7` from 1.8.22 to 1.9.0 - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v1.8.22...v1.9.0) Updates `kotlin-stdlib-jdk8` from 1.8.22 to 1.9.0 - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v1.8.22...v1.9.0) --- updated-dependencies: - dependency-name: org.jetbrains.kotlin:kotlin-stdlib dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.jetbrains.kotlin:kotlin-stdlib-common dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.jetbrains.kotlin:kotlin-stdlib-jdk7 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.jetbrains.kotlin:kotlin-stdlib-jdk8 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index 9a0a93c715d..62c06f892eb 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -39,7 +39,7 @@ 21.0.1 4.1.94.Final 5.0.7.Final - 1.8.22 + 1.9.0 2.0.4 8.3.9 1.0.1 From 391f233fa508086386d81027196b96e350d479a1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jul 2023 17:30:56 +0000 Subject: [PATCH 064/174] Bump hapi-fhir-structures-r4 from 6.2.2 to 6.6.2 in /sormas-base Bumps hapi-fhir-structures-r4 from 6.2.2 to 6.6.2. --- updated-dependencies: - dependency-name: ca.uhn.hapi.fhir:hapi-fhir-structures-r4 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index 62c06f892eb..582bfe5fe85 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -1159,7 +1159,7 @@ ca.uhn.hapi.fhir hapi-fhir-structures-r4 - 6.2.2 + 6.6.2 compile From e88223878c533c5fa0032391ebd2f4a576d67d5b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Jul 2023 17:16:15 +0000 Subject: [PATCH 065/174] Bump org.jetbrains.kotlin:kotlin-bom from 1.8.22 to 1.9.0 in /sormas-app Bumps [org.jetbrains.kotlin:kotlin-bom](https://github.com/JetBrains/kotlin) from 1.8.22 to 1.9.0. - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v1.8.22...v1.9.0) --- updated-dependencies: - dependency-name: org.jetbrains.kotlin:kotlin-bom dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- sormas-app/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-app/app/build.gradle b/sormas-app/app/build.gradle index 1ce320b144a..189a7551deb 100644 --- a/sormas-app/app/build.gradle +++ b/sormas-app/app/build.gradle @@ -139,7 +139,7 @@ dependencies { implementation 'io.crowdcode.sormas.lbds:lbds-android-messaging:1.4.8' implementation 'org.slf4j:slf4j-api:2.0.7' // Align versions of all Kotlin components - implementation platform("org.jetbrains.kotlin:kotlin-bom:1.8.22") + implementation platform("org.jetbrains.kotlin:kotlin-bom:1.9.0") testImplementation 'junit:junit:4.13.2' testImplementation 'org.hamcrest:hamcrest:2.2' testImplementation 'org.hamcrest:hamcrest-core:2.2' From 2d4fabac7cc70cee1dd2d0fdbe2880f454fb5170 Mon Sep 17 00:00:00 2001 From: Michal Kozakiewicz Date: Fri, 14 Jul 2023 10:01:32 +0200 Subject: [PATCH 066/174] SORQA-1035 Implement "Check Vaccination and Vaccination Status of case when sending from SORMAS to Meldesoftware" - refactoring no.3 --- .../sormas/e2etests/enums/immunizations/VaccineNameValues.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/immunizations/VaccineNameValues.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/immunizations/VaccineNameValues.java index cf41654cc20..14044a2272c 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/immunizations/VaccineNameValues.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/immunizations/VaccineNameValues.java @@ -26,7 +26,7 @@ public enum VaccineNameValues { COMIRNATY("Comirnaty (COVID-19-mRNA Impfstoff)"), MRNA_BIVALENT_BA_1_BIONTECH_PFIZER("mRNA/bivalent BA.1 (BioNTech/Pfizer)"), MRNA_BIVALENT_BA_4_5_BIONTECH_PFIZER("mRNA/bivalent BA.4/5 (BioNTech/Pfizer)"), - COVID_19_Impfstoff_Moderna("COVID-19 Impfstoff Moderna (mRNA-Impfstoff)"), + COVID_19_IMPFSTOFF_MODERNA("COVID-19 Impfstoff Moderna (mRNA-Impfstoff)"), MRNA_BIVALENT_BA_1_MODERNA("mRNA/bivalent BA.1 (Moderna)"), MRNA_BIVALENT_BA_4_5_MODERNA("mRNA/bivalent BA.4/5 (Moderna)"), INAKTIVIERT("inaktiviert (Valneva)"), From 5223fc512cf8b2b30edd75cdafcf21722ef0e4c2 Mon Sep 17 00:00:00 2001 From: Michal Kozakiewicz Date: Fri, 14 Jul 2023 10:31:13 +0200 Subject: [PATCH 067/174] SORQA-1035 Implement "Check Vaccination and Vaccination Status of case when sending from SORMAS to Meldesoftware" - refactoring no.4 --- .../src/test/resources/features/sanity/web/Survnet.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature index bbfb428ce14..97f66c2347d 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature @@ -243,3 +243,4 @@ Feature: Survnet tests And I check if "date of report" in SORMAS generated XML file is correct And I check if "vaccination date" in SORMAS generated XML file is correct And I check if Vaccine name in SORMAS generated XML file is correct + From 44aae04861a57897f6dbc966250676f68b74c57f Mon Sep 17 00:00:00 2001 From: Michal Kozakiewicz Date: Fri, 14 Jul 2023 10:40:32 +0200 Subject: [PATCH 068/174] SORQA-1028 Implement "Symptoms in case when sending from SORMAS to Meldesoftware" - refactor method "I check if Vaccine name in SORMAS generated XML file is correct" --- .../web/application/survnet/SurvNetSteps.java | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java index 8dfbd3f7fb5..c9aa5f79687 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java @@ -131,7 +131,6 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { And( "I check if \"([^\"]*)\" SYMPTOM in SORMAS generated single XML file is correct", (String symptom) -> { - // ToDO -consider to change all expecrted... to mor global expectedValue !!! String expectedValue = null; switch (symptom) { case "Fever": @@ -139,7 +138,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { getValueFromSpecificFieldByName(singleXmlFile, "Symptom0088"); String feverOptionFromUI = symptoms.getFever(); - if (feverOptionFromUI == "JA") expectedValue = "true"; + if (feverOptionFromUI.equals("JA")) expectedValue = "true"; else expectedValue = "false"; softly.assertEquals( @@ -151,7 +150,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { getValueFromSpecificFieldByName(singleXmlFile, "Symptom0101"); String shiveringOptionFromUI = symptoms.getFever(); - if (shiveringOptionFromUI == "JA") expectedValue = "true"; + if (shiveringOptionFromUI.equals("JA")) expectedValue = "true"; else expectedValue = "false"; softly.assertEquals( @@ -163,7 +162,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { getValueFromSpecificFieldByName(singleXmlFile, "Symptom0101"); String headacheOptionFromUI = symptoms.getHeadache(); - if (headacheOptionFromUI == "JA") expectedValue = "true"; + if (headacheOptionFromUI.equals("JA")) expectedValue = "true"; else expectedValue = "false"; softly.assertEquals( @@ -177,7 +176,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { getValueFromSpecificFieldByName(singleXmlFile, "Symptom0101"); String musclePaineOptionFromUI = symptoms.getMusclePain(); - if (musclePaineOptionFromUI == "JA") expectedValue = "true"; + if (musclePaineOptionFromUI.equals("JA")) expectedValue = "true"; else expectedValue = "false"; softly.assertEquals( @@ -191,7 +190,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { getValueFromSpecificFieldByName(singleXmlFile, "Symptom0101"); String feelingIllOptionFromUI = symptoms.getFeelingIll(); - if (feelingIllOptionFromUI == "JA") expectedValue = "true"; + if (feelingIllOptionFromUI.equals("JA")) expectedValue = "true"; else expectedValue = "false"; softly.assertEquals( @@ -206,7 +205,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { String acuteRespiratoryDistressSyndromeOptionFromUI = symptoms.getAcuteRespiratoryDistressSyndrome(); - if (acuteRespiratoryDistressSyndromeOptionFromUI == "JA") expectedValue = "true"; + if (acuteRespiratoryDistressSyndromeOptionFromUI.equals("JA")) expectedValue = "true"; else expectedValue = "false"; softly.assertEquals( @@ -220,7 +219,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { getValueFromSpecificFieldByName(singleXmlFile, "Symptom0103"); String soreThroatOptionFromUI = symptoms.getSoreThroat(); - if (soreThroatOptionFromUI == "JA") expectedValue = "true"; + if (soreThroatOptionFromUI.equals("JA")) expectedValue = "true"; else expectedValue = "false"; softly.assertEquals( @@ -234,7 +233,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { getValueFromSpecificFieldByName(singleXmlFile, "Symptom0130"); String coughOptionFromUI = symptoms.getCough(); - if (coughOptionFromUI == "JA") expectedValue = "true"; + if (coughOptionFromUI.equals("JA")) expectedValue = "true"; else expectedValue = "false"; softly.assertEquals( @@ -246,7 +245,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { getValueFromSpecificFieldByName(singleXmlFile, "Symptom0225"); String runnyNoseOptionFromUI = symptoms.getRunnyNose(); - if (runnyNoseOptionFromUI == "JA") expectedValue = "true"; + if (runnyNoseOptionFromUI.equals("JA")) expectedValue = "true"; else expectedValue = "false"; softly.assertEquals( @@ -259,7 +258,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { String pneumoniaClinicalOrRadiologicOptionFromUI = symptoms.getPneumoniaClinicalOrRadiologic(); - if (pneumoniaClinicalOrRadiologicOptionFromUI == "JA") expectedValue = "true"; + if (pneumoniaClinicalOrRadiologicOptionFromUI.equals("JA")) expectedValue = "true"; else expectedValue = "false"; softly.assertEquals( @@ -274,7 +273,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { String respiratoryDiseaseVentilationOptionFromUI = symptoms.getRespiratoryDiseaseVentilation(); - if (respiratoryDiseaseVentilationOptionFromUI == "JA") expectedValue = "true"; + if (respiratoryDiseaseVentilationOptionFromUI.equals("JA")) expectedValue = "true"; else expectedValue = "false"; softly.assertEquals( @@ -288,7 +287,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { getValueFromSpecificFieldByName(singleXmlFile, "Symptom0418"); String rapidBreathingOptionFromUI = symptoms.getRapidBreathing(); - if (rapidBreathingOptionFromUI == "JA") expectedValue = "true"; + if (rapidBreathingOptionFromUI.equals("JA")) expectedValue = "true"; else expectedValue = "false"; softly.assertEquals( @@ -302,7 +301,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { getValueFromSpecificFieldByName(singleXmlFile, "Symptom0064"); String difficultyBreathingOptionFromUI = symptoms.getDifficultyBreathing(); - if (difficultyBreathingOptionFromUI == "JA") expectedValue = "true"; + if (difficultyBreathingOptionFromUI.equals("JA")) expectedValue = "true"; else expectedValue = "false"; softly.assertEquals( @@ -316,7 +315,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { getValueFromSpecificFieldByName(singleXmlFile, "Symptom0245"); String fastHeartRateOptionFromUI = symptoms.getFastHeartRate(); - if (fastHeartRateOptionFromUI == "JA") expectedValue = "true"; + if (fastHeartRateOptionFromUI.equals("JA")) expectedValue = "true"; else expectedValue = "false"; softly.assertEquals( @@ -330,7 +329,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { getValueFromSpecificFieldByName(singleXmlFile, "Symptom0062"); String diarrheaOptionFromUI = symptoms.getDiarrhea(); - if (diarrheaOptionFromUI == "JA") expectedValue = "true"; + if (diarrheaOptionFromUI.equals("JA")) expectedValue = "true"; else expectedValue = "false"; softly.assertEquals( @@ -342,7 +341,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { getValueFromSpecificFieldByName(singleXmlFile, "Symptom0101"); String nauseaOptionFromUI = symptoms.getNausea(); - if (nauseaOptionFromUI == "JA") expectedValue = "true"; + if (nauseaOptionFromUI.equals("JA")) expectedValue = "true"; else expectedValue = "false"; softly.assertEquals( @@ -354,7 +353,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { getValueFromSpecificFieldByName(singleXmlFile, "Symptom0416"); String lossOfSmellOptionfromUI = symptoms.getLossOfSmell(); - if (lossOfSmellOptionfromUI == "JA") expectedValue = "true"; + if (lossOfSmellOptionfromUI.equals("JA")) expectedValue = "true"; else expectedValue = "false"; softly.assertEquals( @@ -368,7 +367,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { getValueFromSpecificFieldByName(singleXmlFile, "Symptom0417"); String lossOfTasteOptionFromUI = symptoms.getLossOfTaste(); - if (lossOfTasteOptionFromUI == "JA") expectedValue = "true"; + if (lossOfTasteOptionFromUI.equals("JA")) expectedValue = "true"; else expectedValue = "false"; softly.assertEquals( @@ -383,7 +382,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { String otherNonHemorrhagicSymptomsOptionFromUI = symptoms.getOtherNonHemorrhagicSymptoms(); - if (otherNonHemorrhagicSymptomsOptionFromUI == "JA") expectedValue = "true"; + if (otherNonHemorrhagicSymptomsOptionFromUI.equals("JA")) expectedValue = "true"; else expectedValue = "false"; softly.assertEquals( From f41387321b27efebe4de08fee5e87324ccb87f55 Mon Sep 17 00:00:00 2001 From: Carina Paul <47103965+carina29@users.noreply.github.com> Date: Fri, 14 Jul 2023 12:06:29 +0300 Subject: [PATCH 069/174] =?UTF-8?q?#11931=20-=20extract=20deleteAllSelecte?= =?UTF-8?q?d=20items=20from=20CaseController=20to=20Delet=E2=80=A6=20(#120?= =?UTF-8?q?91)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * #11931 - extract deleteAllSelected to DeleteRestoreController and PermanentDeleteController and add bulk progress bar --- .../de/symeda/sormas/api/DeletableFacade.java | 6 + .../api/PermanentlyDeletableFacade.java | 10 + .../de/symeda/sormas/api/caze/CaseFacade.java | 2 - .../sormas/api/contact/ContactFacade.java | 3 - .../symeda/sormas/api/event/EventFacade.java | 3 - .../ExternalMessageFacade.java | 7 +- .../de/symeda/sormas/api/i18n/Strings.java | 47 ++- .../api/immunization/ImmunizationFacade.java | 3 - .../sormas/api/sample/SampleFacade.java | 2 - .../de/symeda/sormas/api/task/TaskFacade.java | 5 +- .../symeda/sormas/api/visit/VisitFacade.java | 7 +- .../src/main/resources/strings.properties | 71 +++- .../backend/campaign/CampaignFacadeEjb.java | 12 + .../sormas/backend/caze/CaseFacadeEjb.java | 64 ++-- .../backend/contact/ContactFacadeEjb.java | 60 ++-- .../environment/EnvironmentFacadeEjb.java | 18 +- .../sormas/backend/event/EventFacadeEjb.java | 70 ++-- .../event/EventParticipantFacadeEjb.java | 46 ++- .../ExternalMessageFacadeEjb.java | 23 +- .../immunization/ImmunizationFacadeEjb.java | 46 ++- .../backend/sample/SampleFacadeEjb.java | 22 +- .../sormas/backend/task/TaskFacadeEjb.java | 23 +- .../travelentry/TravelEntryFacadeEjb.java | 47 +++ .../sormas/backend/visit/VisitFacadeEjb.java | 34 +- .../sormas/backend/ArchitectureTest.java | 3 +- .../backend/caze/CaseFacadeEjbTest.java | 4 +- .../backend/contact/ContactFacadeEjbTest.java | 4 +- .../ExternalMessageServiceTest.java | 4 +- .../backend/sample/SampleFacadeEjbTest.java | 10 +- .../backend/task/TaskFacadeEjbTest.java | 2 +- .../sormas/rest/resources/CaseResource.java | 2 +- .../rest/resources/ContactResource.java | 2 +- .../sormas/rest/resources/EventResource.java | 2 +- .../rest/resources/ImmunizationResource.java | 3 +- .../symeda/sormas/ui/ControllerProvider.java | 6 + .../sormas/ui/caze/CaseContactsView.java | 3 +- .../symeda/sormas/ui/caze/CaseController.java | 101 ++---- .../symeda/sormas/ui/caze/CaseVisitsView.java | 2 +- .../de/symeda/sormas/ui/caze/CasesView.java | 4 +- .../sormas/ui/contact/ContactController.java | 55 +-- .../sormas/ui/contact/ContactVisitsView.java | 8 +- .../sormas/ui/contact/ContactsView.java | 4 +- .../sormas/ui/events/EventController.java | 132 ++------ .../events/EventParticipantsController.java | 71 ++-- .../ui/events/EventParticipantsView.java | 4 +- .../symeda/sormas/ui/events/EventsView.java | 4 +- .../ExternalMessageController.java | 65 ++-- .../externalmessage/ExternalMessagesView.java | 2 +- .../sormas/ui/samples/SampleController.java | 61 ++-- .../ui/samples/SampleGridComponent.java | 16 +- .../symeda/sormas/ui/task/TaskController.java | 50 ++- .../sormas/ui/task/TaskGridComponent.java | 2 +- .../ui/travelentry/TravelEntriesView.java | 6 +- .../ui/travelentry/TravelEntryController.java | 80 +++-- .../sormas/ui/utils/ArchivingController.java | 11 +- .../sormas/ui/utils/BulkOperationHandler.java | 169 ++++++++-- .../ui/utils/CoreEntityRestoreMessages.java | 115 ------- .../ui/utils/DeleteRestoreController.java | 200 ++++++++--- .../ui/utils/DeleteRestoreHandlers.java | 211 ++++++++++++ .../ui/utils/DeleteRestoreMessages.java | 313 ++++++++++++++++++ .../ui/utils/PermanentDeleteController.java | 107 ++++++ .../sormas/ui/visit/VisitController.java | 55 +-- 62 files changed, 1746 insertions(+), 778 deletions(-) create mode 100644 sormas-api/src/main/java/de/symeda/sormas/api/PermanentlyDeletableFacade.java delete mode 100644 sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CoreEntityRestoreMessages.java create mode 100644 sormas-ui/src/main/java/de/symeda/sormas/ui/utils/DeleteRestoreHandlers.java create mode 100644 sormas-ui/src/main/java/de/symeda/sormas/ui/utils/DeleteRestoreMessages.java create mode 100644 sormas-ui/src/main/java/de/symeda/sormas/ui/utils/PermanentDeleteController.java diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/DeletableFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/DeletableFacade.java index 12f755cabb0..11fb0cd300c 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/DeletableFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/DeletableFacade.java @@ -1,12 +1,18 @@ package de.symeda.sormas.api; +import java.util.List; + import de.symeda.sormas.api.common.DeletionDetails; public interface DeletableFacade { void delete(String uuid, DeletionDetails deletionDetails); + List delete(List uuids, DeletionDetails deletionDetails); + void restore(String uuid); + List restore(List uuids); + boolean isDeleted(String uuid); } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/PermanentlyDeletableFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/PermanentlyDeletableFacade.java new file mode 100644 index 00000000000..9843e82ba13 --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/PermanentlyDeletableFacade.java @@ -0,0 +1,10 @@ +package de.symeda.sormas.api; + +import java.util.List; + +public interface PermanentlyDeletableFacade { + + void delete(String uuid); + + void delete(List uuids); +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseFacade.java index aba4b35dbe6..f7aceb299db 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseFacade.java @@ -124,8 +124,6 @@ Long countCasesForMap( List getAllCasesOfPerson(String personUuid); - List deleteCases(List caseUuids, DeletionDetails deletionDetails); - void deleteWithContacts(String caseUuid, DeletionDetails deletionDetails); Date getOldestCaseOnsetDate(); diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactFacade.java index 48a619657dc..965bbb00998 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactFacade.java @@ -33,7 +33,6 @@ import de.symeda.sormas.api.MergeFacade; import de.symeda.sormas.api.caze.CaseReferenceDto; import de.symeda.sormas.api.caze.CoreAndPersonDto; -import de.symeda.sormas.api.common.DeletionDetails; import de.symeda.sormas.api.common.Page; import de.symeda.sormas.api.dashboard.DashboardContactDto; import de.symeda.sormas.api.externaldata.ExternalDataDto; @@ -61,8 +60,6 @@ public interface ContactFacade extends CoreFacade getContactsForMap(RegionReferenceDto regionRef, DistrictReferenceDto districtRef, Disease disease, Date from, Date to); - List deleteContacts(List contactUuids, DeletionDetails deletionDetails); - FollowUpPeriodDto getCalculatedFollowUpUntilDate(ContactDto contactDto, boolean ignoreOverwrite); List getEntriesList(String personUuid, Integer first, Integer max); diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/event/EventFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/event/EventFacade.java index e8ec4ea4d52..fa4f5a77e43 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/event/EventFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/event/EventFacade.java @@ -28,7 +28,6 @@ import de.symeda.sormas.api.CoreFacade; import de.symeda.sormas.api.caze.CaseDataDto; -import de.symeda.sormas.api.common.DeletionDetails; import de.symeda.sormas.api.common.Page; import de.symeda.sormas.api.externaldata.ExternalDataDto; import de.symeda.sormas.api.externaldata.ExternalDataUpdateException; @@ -46,8 +45,6 @@ public interface EventFacade extends CoreFacade getAllByCase(CaseDataDto caseDataDto); - List deleteEvents(List eventUuids, DeletionDetails deletionDetails); - Page getIndexPage(@NotNull EventCriteria eventCriteria, Integer offset, Integer size, List sortProperties); List getExportList(EventCriteria eventCriteria, Collection selectedRows, Integer first, Integer max); diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/externalmessage/ExternalMessageFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/externalmessage/ExternalMessageFacade.java index 05424497e63..8757b71f9b2 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/externalmessage/ExternalMessageFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/externalmessage/ExternalMessageFacade.java @@ -7,6 +7,7 @@ import javax.naming.NamingException; import javax.validation.Valid; +import de.symeda.sormas.api.PermanentlyDeletableFacade; import de.symeda.sormas.api.ReferenceDto; import de.symeda.sormas.api.caze.surveillancereport.SurveillanceReportReferenceDto; import de.symeda.sormas.api.common.Page; @@ -15,7 +16,7 @@ import de.symeda.sormas.api.utils.SortProperty; @Remote -public interface ExternalMessageFacade { +public interface ExternalMessageFacade extends PermanentlyDeletableFacade { ExternalMessageDto save(@Valid ExternalMessageDto dto); @@ -24,10 +25,6 @@ public interface ExternalMessageFacade { // Also returns deleted lab messages ExternalMessageDto getByUuid(String uuid); - void deleteExternalMessage(String uuid); - - void deleteExternalMessages(List uuids); - void bulkAssignExternalMessages(List uuids, UserReferenceDto userRef); // Does not return deleted lab messages diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java index c2ebef8d429..f31f282d8c7 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java @@ -132,6 +132,7 @@ public interface Strings { String confirmationDeleteCaseContacts = "confirmationDeleteCaseContacts"; String confirmationDeleteCases = "confirmationDeleteCases"; String confirmationDeleteContacts = "confirmationDeleteContacts"; + String confirmationDeleteEntities = "confirmationDeleteEntities"; String confirmationDeleteEntity = "confirmationDeleteEntity"; String confirmationDeleteEntityWithDetails = "confirmationDeleteEntityWithDetails"; String confirmationDeleteEventParticipants = "confirmationDeleteEventParticipants"; @@ -251,6 +252,7 @@ public interface Strings { String entityEventParticipants = "entityEventParticipants"; String entityEvents = "entityEvents"; String entityExposure = "entityExposure"; + String entityExternalMessages = "entityExternalMessages"; String entityFacilities = "entityFacilities"; String entityFeatureConfigurations = "entityFeatureConfigurations"; String entityGathering = "entityGathering"; @@ -570,7 +572,6 @@ public interface Strings { String headingExternalMessageProcessSample = "headingExternalMessageProcessSample"; String headingExternalMessageSampleInformation = "headingExternalMessageSampleInformation"; String headingExternalMessagesDeleted = "headingExternalMessagesDeleted"; - String headingExternalMessagesDeleteProcessed = "headingExternalMessagesDeleteProcessed"; String headingFatalities = "headingFatalities"; String headingFetchExternalMessages = "headingFetchExternalMessages"; String headingFileExists = "headingFileExists"; @@ -722,13 +723,20 @@ public interface Strings { String headingSimilarImmunization = "headingSimilarImmunization"; String headingSomeCasesNotDeleted = "headingSomeCasesNotDeleted"; String headingSomeCasesNotRestored = "headingSomeCasesNotRestored"; + String headingSomeContactsNotDeleted = "headingSomeContactsNotDeleted"; String headingSomeContactsNotRestored = "headingSomeContactsNotRestored"; + String headingSomeEventParticipantsNotDeleted = "headingSomeEventParticipantsNotDeleted"; String headingSomeEventParticipantsNotRestored = "headingSomeEventParticipantsNotRestored"; String headingSomeEventsNotDeleted = "headingSomeEventsNotDeleted"; String headingSomeEventsNotRestored = "headingSomeEventsNotRestored"; + String headingSomeExternalMessagesNotDeleted = "headingSomeExternalMessagesNotDeleted"; String headingSomeImmunizationsNotRestored = "headingSomeImmunizationsNotRestored"; + String headingSomeSamplesNotDeleted = "headingSomeSamplesNotDeleted"; String headingSomeSamplesNotRestored = "headingSomeSamplesNotRestored"; + String headingSomeTasksNotDeleted = "headingSomeTasksNotDeleted"; + String headingSomeTravelEntriesNotDeleted = "headingSomeTravelEntriesNotDeleted"; String headingSomeTravelEntriesNotRestored = "headingSomeTravelEntriesNotRestored"; + String headingSomeVisitsNotDeleted = "headingSomeVisitsNotDeleted"; String headingSormasToSormasCanAcceptContactsWithoutCase = "headingSormasToSormasCanAcceptContactsWithoutCase"; String headingSormasToSormasCantShareContactWithoutCase = "headingSormasToSormasCantShareContactWithoutCase"; String headingSormasToSormasDuplicateDetection = "headingSormasToSormasDuplicateDetection"; @@ -799,7 +807,10 @@ public interface Strings { String infoBulkProcess = "infoBulkProcess"; String infoBulkProcessCancelled = "infoBulkProcessCancelled"; String infoBulkProcessFinished = "infoBulkProcessFinished"; + String infoBulkProcessFinishedWithIneligibleItems = "infoBulkProcessFinishedWithIneligibleItems"; String infoBulkProcessFinishedWithSkips = "infoBulkProcessFinishedWithSkips"; + String infoBulkProcessFinishedWithSkipsOutsideJurisdiction = "infoBulkProcessFinishedWithSkipsOutsideJurisdiction"; + String infoBulkProcessNoEligibleEntries = "infoBulkProcessNoEligibleEntries"; String infoBulkUnresponsiveWindowHint = "infoBulkUnresponsiveWindowHint"; String infoCalculateCompleteness = "infoCalculateCompleteness"; String infoCampaignsDashboard = "infoCampaignsDashboard"; @@ -1039,7 +1050,8 @@ public interface Strings { String messageCaseSavedClassificationChanged = "messageCaseSavedClassificationChanged"; String messageCasesDeleted = "messageCasesDeleted"; String messageCasesMerged = "messageCasesMerged"; - String messageCasesNotDeletedReasonExternalSurveillanceTool = "messageCasesNotDeletedReasonExternalSurveillanceTool"; + String messageCasesNotDeleted = "messageCasesNotDeleted"; + String messageCasesNotDeletedExternalReason = "messageCasesNotDeletedExternalReason"; String messageCasesNotRestored = "messageCasesNotRestored"; String messageCasesRestored = "messageCasesRestored"; String messageCaseTransfered = "messageCaseTransfered"; @@ -1072,6 +1084,8 @@ public interface Strings { String messageContactSaved = "messageContactSaved"; String messageContactsDeleted = "messageContactsDeleted"; String messageContactsMerged = "messageContactsMerged"; + String messageContactsNotDeleted = "messageContactsNotDeleted"; + String messageContactsNotRestored = "messageContactsNotRestored"; String messageContactsRestored = "messageContactsRestored"; String messageContactToCaseConfirmationRequired = "messageContactToCaseConfirmationRequired"; String messageContinentArchived = "messageContinentArchived"; @@ -1089,19 +1103,25 @@ public interface Strings { String messageCountCasesNotDeleted = "messageCountCasesNotDeleted"; String messageCountCasesNotRestored = "messageCountCasesNotRestored"; String messageCountContactsAlreadyInEvent = "messageCountContactsAlreadyInEvent"; + String messageCountContactsNotDeleted = "messageCountContactsNotDeleted"; String messageCountContactsNotRestored = "messageCountContactsNotRestored"; + String messageCountEventParticipantsNotDeleted = "messageCountEventParticipantsNotDeleted"; String messageCountEventParticipantsNotRestored = "messageCountEventParticipantsNotRestored"; String messageCountEventsNotDeleted = "messageCountEventsNotDeleted"; - String messageCountEventsNotDeletedExternalSurveillanceTool = "messageCountEventsNotDeletedExternalSurveillanceTool"; String messageCountEventsNotRestored = "messageCountEventsNotRestored"; + String messageCountExternalMessagesNotDeleted = "messageCountExternalMessagesNotDeleted"; String messageCountImmunizationsNotRestored = "messageCountImmunizationsNotRestored"; String messageCountriesArchived = "messageCountriesArchived"; String messageCountriesDearchived = "messageCountriesDearchived"; String messageCountryArchived = "messageCountryArchived"; String messageCountryDearchived = "messageCountryDearchived"; String messageCountryDearchivingNotPossible = "messageCountryDearchivingNotPossible"; + String messageCountSamplesNotDeleted = "messageCountSamplesNotDeleted"; String messageCountSamplesNotRestored = "messageCountSamplesNotRestored"; + String messageCountTasksNotDeleted = "messageCountTasksNotDeleted"; + String messageCountTravelEntriesNotDeleted = "messageCountTravelEntriesNotDeleted"; String messageCountTravelEntriesNotRestored = "messageCountTravelEntriesNotRestored"; + String messageCountVisitsNotDeleted = "messageCountVisitsNotDeleted"; String messageCreateCollectionTask = "messageCreateCollectionTask"; String messageDatabaseExportFailed = "messageDatabaseExportFailed"; String messageDeleteImmunizationVaccinations = "messageDeleteImmunizationVaccinations"; @@ -1148,14 +1168,18 @@ public interface Strings { String messageEventParticipantResponsibleJurisdictionUpdated = "messageEventParticipantResponsibleJurisdictionUpdated"; String messageEventParticipantSaved = "messageEventParticipantSaved"; String messageEventParticipantsDeleted = "messageEventParticipantsDeleted"; + String messageEventParticipantsNotDeleted = "messageEventParticipantsNotDeleted"; + String messageEventParticipantsNotRestored = "messageEventParticipantsNotRestored"; String messageEventParticipantsRestored = "messageEventParticipantsRestored"; String messageEventParticipantToCaseWithoutEventDisease = "messageEventParticipantToCaseWithoutEventDisease"; String messageEventParticipantToContactWithoutEventDisease = "messageEventParticipantToContactWithoutEventDisease"; String messageEventParticipationUnlinked = "messageEventParticipationUnlinked"; String messageEventSaved = "messageEventSaved"; String messageEventsDeleted = "messageEventsDeleted"; - String messageEventsNotDeletedReason = "messageEventsNotDeletedReason"; - String messageEventsNotDeletedReasonExternalSurveillanceTool = "messageEventsNotDeletedReasonExternalSurveillanceTool"; + String messageEventsNotDeleted = "messageEventsNotDeleted"; + String messageEventsNotDeletedExternalReason = "messageEventsNotDeletedExternalReason"; + String messageEventsNotDeletedLinkedEntitiesReason = "messageEventsNotDeletedLinkedEntitiesReason"; + String messageEventsNotRestored = "messageEventsNotRestored"; String messageEventsRestored = "messageEventsRestored"; String messageEventsSentToSurvnet = "messageEventsSentToSurvnet"; String messageEventSubordinateEventUnlinked = "messageEventSubordinateEventUnlinked"; @@ -1168,7 +1192,8 @@ public interface Strings { String messageExternalLabResultsAdapterNotFound = "messageExternalLabResultsAdapterNotFound"; String messageExternalMessagesAssigned = "messageExternalMessagesAssigned"; String messageExternalMessagesDeleted = "messageExternalMessagesDeleted"; - String messageExternalMessagesDeleteProcessed = "messageExternalMessagesDeleteProcessed"; + String messageExternalMessagesEligibleForDeletion = "messageExternalMessagesEligibleForDeletion"; + String messageExternalMessagesNotDeleted = "messageExternalMessagesNotDeleted"; String messageFacilitiesArchived = "messageFacilitiesArchived"; String messageFacilitiesDearchived = "messageFacilitiesDearchived"; String messageFacilityArchived = "messageFacilityArchived"; @@ -1186,6 +1211,9 @@ public interface Strings { String messageImmunizationOutsideJurisdictionDeletionDenied = "messageImmunizationOutsideJurisdictionDeletionDenied"; String messageImmunizationSaved = "messageImmunizationSaved"; String messageImmunizationSavedVaccinationStatusUpdated = "messageImmunizationSavedVaccinationStatusUpdated"; + String messageImmunizationsDeleted = "messageImmunizationsDeleted"; + String messageImmunizationsNotDeleted = "messageImmunizationsNotDeleted"; + String messageImmunizationsNotRestored = "messageImmunizationsNotRestored"; String messageImmunizationsRestored = "messageImmunizationsRestored"; String messageImportCanceled = "messageImportCanceled"; String messageImportCanceledErrors = "messageImportCanceledErrors"; @@ -1221,6 +1249,7 @@ public interface Strings { String messageNoCsvFile = "messageNoCsvFile"; String messageNoDocumentTemplateUploadFile = "messageNoDocumentTemplateUploadFile"; String messageNoDocumentUploadFile = "messageNoDocumentUploadFile"; + String messageNoEligibleEventForDeletionSelected = "messageNoEligibleEventForDeletionSelected"; String messageNoEndDate = "messageNoEndDate"; String messageNoEnvironmentsSelected = "messageNoEnvironmentsSelected"; String messageNoEventFound = "messageNoEventFound"; @@ -1276,6 +1305,8 @@ public interface Strings { String messageSampleOpened = "messageSampleOpened"; String messageSampleSaved = "messageSampleSaved"; String messageSamplesDeleted = "messageSamplesDeleted"; + String messageSamplesNotDeleted = "messageSamplesNotDeleted"; + String messageSamplesNotRestored = "messageSamplesNotRestored"; String messageSamplesRestored = "messageSamplesRestored"; String messageSelectedPeriodTooLong = "messageSelectedPeriodTooLong"; String messageSetContactRegionAndDistrict = "messageSetContactRegionAndDistrict"; @@ -1305,9 +1336,12 @@ public interface Strings { String messageTaskDearchived = "messageTaskDearchived"; String messageTasksDeleted = "messageTasksDeleted"; String messageTasksEdited = "messageTasksEdited"; + String messageTasksNotDeleted = "messageTasksNotDeleted"; String messageTemplateNotAvailable = "messageTemplateNotAvailable"; String messageThisPersonAlreadyEventParticipant = "messageThisPersonAlreadyEventParticipant"; String messageTravelEntriesDeleted = "messageTravelEntriesDeleted"; + String messageTravelEntriesNotDeleted = "messageTravelEntriesNotDeleted"; + String messageTravelEntriesNotRestored = "messageTravelEntriesNotRestored"; String messageTravelEntriesRestored = "messageTravelEntriesRestored"; String messageTravelEntryArchived = "messageTravelEntryArchived"; String messageTravelEntryDearchived = "messageTravelEntryDearchived"; @@ -1341,6 +1375,7 @@ public interface Strings { String messageVaccinationNotRelevantForEventParticipant = "messageVaccinationNotRelevantForEventParticipant"; String messageVaccinationOutsideJurisdictionDeletionDenied = "messageVaccinationOutsideJurisdictionDeletionDenied"; String messageVisitsDeleted = "messageVisitsDeleted"; + String messageVisitsNotDeleted = "messageVisitsNotDeleted"; String messageWrongFileType = "messageWrongFileType"; String messageWrongTemplateFileType = "messageWrongTemplateFileType"; String min = "min"; diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/immunization/ImmunizationFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/immunization/ImmunizationFacade.java index f943f5ce4ea..ebe8f6cc587 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/immunization/ImmunizationFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/immunization/ImmunizationFacade.java @@ -21,7 +21,6 @@ import javax.ejb.Remote; import de.symeda.sormas.api.CoreFacade; -import de.symeda.sormas.api.common.DeletionDetails; import de.symeda.sormas.api.common.Page; import de.symeda.sormas.api.utils.SortProperty; @@ -32,8 +31,6 @@ public interface ImmunizationFacade extends CoreFacade getDeletedUuidsSince(Date since); - List deleteImmunizations(List immunizationUuids, DeletionDetails deletionDetails); - List getSimilarImmunizations(ImmunizationSimilarityCriteria criteria); void updateImmunizationStatuses(); diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/sample/SampleFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/sample/SampleFacade.java index d388fbfe51a..59c3efd5fd1 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/sample/SampleFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/sample/SampleFacade.java @@ -63,8 +63,6 @@ public interface SampleFacade extends DeletableFacade { List getByUuids(List uuids); - void deleteAllSamples(List sampleUuids, DeletionDetails deletionDetails); - List deleteSamples(List sampleUuids, DeletionDetails deletionDetails); void validate(@Valid SampleDto sample, boolean checkAssociatedEntities) throws ValidationRuntimeException; diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/task/TaskFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/task/TaskFacade.java index 34a4e71a30f..89dff078a47 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/task/TaskFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/task/TaskFacade.java @@ -27,6 +27,7 @@ import de.symeda.sormas.api.ArchivableFacade; import de.symeda.sormas.api.EditPermissionType; +import de.symeda.sormas.api.PermanentlyDeletableFacade; import de.symeda.sormas.api.caze.CaseReferenceDto; import de.symeda.sormas.api.common.Page; import de.symeda.sormas.api.contact.ContactReferenceDto; @@ -34,7 +35,7 @@ import de.symeda.sormas.api.utils.SortProperty; @Remote -public interface TaskFacade extends ArchivableFacade { +public interface TaskFacade extends PermanentlyDeletableFacade, ArchivableFacade { TaskDto saveTask(@Valid TaskDto dto); @@ -64,8 +65,6 @@ public interface TaskFacade extends ArchivableFacade { List getAllActiveUuids(); - void deleteTask(TaskDto taskDto); - List deleteTasks(List taskUuids); long count(TaskCriteria criteria); diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/visit/VisitFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/visit/VisitFacade.java index 01cb539f476..e8dc45df9bf 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/visit/VisitFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/visit/VisitFacade.java @@ -23,6 +23,7 @@ import javax.validation.Valid; import de.symeda.sormas.api.BaseFacade; +import de.symeda.sormas.api.PermanentlyDeletableFacade; import de.symeda.sormas.api.caze.CaseReferenceDto; import de.symeda.sormas.api.common.Page; import de.symeda.sormas.api.contact.ContactReferenceDto; @@ -30,7 +31,7 @@ import de.symeda.sormas.api.utils.SortProperty; @Remote -public interface VisitFacade extends BaseFacade { +public interface VisitFacade extends BaseFacade, PermanentlyDeletableFacade { List getAllActiveVisitsAfter(Date date); @@ -46,8 +47,6 @@ public interface VisitFacade extends BaseFacade getAllActiveVisitsAfter(Date date, Integer batchSize, String lastSynchronizedUuid); - void deleteVisit(String visitUuid); - Page getIndexPage(VisitCriteria visitCriteria, Integer first, Integer max, List sortProperties); List getVisitsExportList( @@ -65,4 +64,6 @@ List getVisitsExportList( List getVisitsByContactAndPeriod(ContactReferenceDto contactRef, Date begin, Date end); VisitDto getLastVisitByCase(CaseReferenceDto caseRef); + + List deleteVisits(List uuids); } diff --git a/sormas-api/src/main/resources/strings.properties b/sormas-api/src/main/resources/strings.properties index dbf71292e82..ce789a33297 100644 --- a/sormas-api/src/main/resources/strings.properties +++ b/sormas-api/src/main/resources/strings.properties @@ -152,6 +152,7 @@ confirmationDearchiveEventParticipant = Are you sure you want to de-archive this confirmationDearchiveEventGroup = Are you sure you want to de-archive this event group? This will make it appear in the normal event group directory again. confirmationDeleteCases = Are you sure you want to delete all %d selected cases?

If referenced by other data in the system, those references will be removed, which cannot be automatically undone. confirmationDeleteContacts = Are you sure you want to delete all %d selected contacts?

If referenced by other data in the system, those references will be removed, which cannot be automatically undone. +confirmationDeleteEntities = Are you sure you want to delete all %d selected %s?

If referenced by other data in the system, those references will be removed, which cannot be automatically undone. confirmationRestoreEntities = Are you sure you want to restore all %d selected %s? confirmationDeleteEntity = Are you sure you want to delete this %s?

If referenced by other data in the system, those references will be removed, which cannot be automatically undone. confirmationDeleteEntityWithDetails = Are you sure you want to delete this %s?
%s
If referenced by other data in the system, those references will be removed, which cannot be automatically undone. @@ -298,6 +299,7 @@ entityTreatments = Treatments entityUser = User entityUsers = Users entityExposure = Exposure +entityExternalMessages = External messages entityCampaignData = Campaign Data entityCampaignDataForm=campaign data form entityStatistics = Statistics @@ -713,13 +715,20 @@ headingNoEventFound = No event found headingEventNotDeleted = Event not deleted headingSomeCasesNotDeleted = Some cases were not deleted headingSomeCasesNotRestored = Some cases were not restored +headingSomeContactsNotDeleted = Some contacts were not deleted headingSomeContactsNotRestored = Some contacts were not restored headingSomeEventsNotRestored = Some events were not restored +headingSomeEventParticipantsNotDeleted = Some event participants were not deleted headingSomeEventParticipantsNotRestored = Some event participants were not restored headingSomeImmunizationsNotRestored = Some immunizations were not restored +headingSomeSamplesNotDeleted = Some samples were not deleted headingSomeSamplesNotRestored = Some samples were not restored +headingSomeTasksNotDeleted = Some tasks were not deleted +headingSomeTravelEntriesNotDeleted = Some travel entries were not deleted headingSomeTravelEntriesNotRestored = Some travel entries were not restored +headingSomeVisitsNotDeleted = Some visits were not deleted headingSomeEventsNotDeleted = Some events were not deleted +headingSomeExternalMessagesNotDeleted = Some external messages were not deleted headingContactConfirmationRequired = Contact confirmation required headingContactConversionFollowUpCommentLarge = Follow up comment will exceed the max characters allowed headingSelectSourceCase = Select Source Case @@ -751,7 +760,6 @@ headingEventGroupUnlinkEventIssue = Issue while unlinking events to event group headingExportUserRightsFailed = Export user rights failed headingExternalMessageDownload = Download message headingNoExternalMessagesSelected = No messages selected -headingExternalMessagesDeleteProcessed = Delete processed message(s) headingExternalMessagesDeleted = Messages deleted headingExternalMessageCorrection = Correction message headingExternalMessageProcessSample = Process sample and test reports @@ -991,7 +999,10 @@ infoNoAccessToPersonEntities = You don't have the necessary user rights to view infoDashboardFinalLaboratoryResult = When a case has multiple samples, only the final laboratory result of the sample with the latest sample collection date is considered. infoBulkProcess = %d selected entries are currently being processed. This may take a while. The progress will be updated for each 20 entries that have been processed. infoBulkProcessFinished = All selected entries have been processed!
You can now close this window. -infoBulkProcessFinishedWithSkips = Bulk process has been successfully completed!
However, some of the selected entries could not be processed, most likely because they were outside your jurisdiction or already archived. +infoBulkProcessFinishedWithIneligibleItems = Bulk process has been successfully completed!
However, some of the selected entries could not be processed, because they were not eligible. +infoBulkProcessFinishedWithSkipsOutsideJurisdiction = Bulk process has been successfully completed!
However, some of the selected entries could not be processed, most likely because they were outside your jurisdiction. +infoBulkProcessFinishedWithSkips = Bulk process has been successfully completed!
However, some of the selected entries could not be processed, most likely because they were outside your jurisdiction, already archived or not eligible. +infoBulkProcessNoEligibleEntries = Bulk process has been cancelled because there are no eligible entries for this operation! infoBulkProcessCancelled = Bulk process has been cancelled!
All selected entries up until this point have been processed. You can now close this window. All not yet processed entries will still be selected. infoBulkUnresponsiveWindowHint = Hint: If the progress bar seems to be unresponsive and no progress is visible after a while, try to click this popup window or resize your browser window. @@ -1028,17 +1039,26 @@ messageCaseRelationToEventWithoutDisease=It is not possible to link a case to an messageCaseSaved = Case saved messageCaseSavedClassificationChanged = Case saved. The classification was automatically changed to %s. messageCaseTransfered = Case has been transfered to another facility -messageCasesDeleted = All selected cases have been deleted +messageCasesNotDeleted = The cases mentioned in the above list of UUIDs could not be deleted. +messageCasesNotDeletedExternalReason = The cases mentioned in the above list of UUIDs could not be deleted because the communication with the reporting tool failed. +messageCasesDeleted = All selected eligible cases have been deleted messageCaseOutsideJurisdictionDeletionDenied = The case outside user's jurisdiction cannot be deleted messageCasesMerged = Cases merged and duplicate case deleted. messageCasesRestored = All selected cases have been restored +messageContactsNotRestored = The contacts mentioned in the above list of UUIDs could not be restored. messageContactsRestored = All selected contacts have been restored +messageEventsNotRestored = The events mentioned in the above list of UUIDs could not be restored. messageEventsRestored = All selected events have been restored +messageEventParticipantsNotRestored = The event participants mentioned in the above list of UUIDs could not be restored. messageEventParticipantsRestored = All selected event participants have been restored +messageImmunizationsNotDeleted = The immunizations mentioned in the above list of UUIDs could not be deleted. +messageImmunizationsDeleted = All selected eligible immunizations have been deleted +messageImmunizationsNotRestored = The immunizations mentioned in the above list of UUIDs could not be restored. messageImmunizationsRestored = All selected immunizations have been restored +messageSamplesNotRestored = The samples mentioned in the above list of UUIDs could not be restored. messageSamplesRestored = All selected samples have been restored +messageTravelEntriesNotRestored = The travel entries mentioned in the above list of UUIDs could not be restored. messageTravelEntriesRestored = All selected travel entries have been restored -messageCasesNotDeletedReasonExternalSurveillanceTool = Some cases were not deleted because the communication with the reporting tool failed. messageCasesNotRestored = The cases mentioned in the above list of UUIDs could not be restored. messageChangePathogenTestResult = The result of this pathogen test differs from the current overall pathogen test result of the sample. Do you want to update its result to %s? messageCheckInputData = Please check the input data @@ -1059,7 +1079,8 @@ messageContactCreated=New contact created messageContactArchived = Contact has been archived messageContactDearchived = Contact has been de-archived messageContactSaved = Contact data saved -messageContactsDeleted = All selected contacts have been deleted +messageContactsNotDeleted = The contacts mentioned in the above list of UUIDs could not be deleted. +messageContactsDeleted = All selected eligible contacts have been deleted messageContactOutsideJurisdictionDeletionDenied = The contact outside user's jurisdiction cannot be deleted messageContactDuplicateDeleted = The duplicate contact has been deleted. messageContactsMerged = Contacts merged and duplicate contact deleted. @@ -1097,27 +1118,35 @@ messageEventParticipantDearchived = Event participant has been de-archived messageEventParticipantCreated = New person created messageEventParticipantSaved = Person data saved messageEventParticipantOutsideJurisdictionDeletionDenied = The event participant outside user's jurisdiction cannot be deleted -messageEventParticipantsDeleted = All selected event participants have been deleted +messageEventParticipantsNotDeleted = The event participants mentioned in the above list of UUIDs could not be deleted. +messageEventParticipantsDeleted = All selected eligible event participants have been deleted messageEventParticipantResponsibleJurisdictionUpdated = Changing or removing the responsible jurisdiction of this event participant could make you lose access to its personal details and/or disallow you to edit it in the future. Are you sure you want to proceed? messageEventParticipantToCaseWithoutEventDisease=It is not possible to create cases from an event participant if the disease of the event has not been set messageEventParticipantToContactWithoutEventDisease=It is not possible to create a contact from an event participant if the disease of the event has not been set messageEventJurisdictionUpdated = Changing or removing the jurisdiction of this event could make you lose access to its personal details and/or disallow you to edit it in the future. Are you sure you want to proceed? messageEventSaved = Event data saved messageEventGroupSaved = Event group data saved -messageEventsDeleted = All selected events have been deleted +messageEventsNotDeleted = The events mentioned in the above list of UUIDs could not be deleted. +messageEventsDeleted = All selected eligible events have been deleted messageEventsSentToSurvnet = All selected events have been sent to SurvNet -messageCountCasesNotDeleted = %s cases not deleted. CasesIds not deleted: %s +messageCountCasesNotDeleted = %s cases not deleted. UUIDs of cases not deleted: %s messageCountCasesNotRestored = %s cases not restored. UUIDs of cases not restored: %s +messageCountContactsNotDeleted = %s contacts not deleted. UUIDs of contacts not deleted: %s messageCountContactsNotRestored = %s contacts not restored. UUIDs of contact not restored: %s messageCountEventsNotRestored = %s events not restored. UUIDs of events not restored: %s +messageCountEventParticipantsNotDeleted = %s event participants not deleted. UUIDs of event participants not deleted: %s messageCountEventParticipantsNotRestored = %s event participants not restored. UUIDs of event participants not restored: %s +messageCountExternalMessagesNotDeleted = %s external messages not deleted. UUIDs of external messages not deleted: %s messageCountImmunizationsNotRestored = %s immunizations not restored. UUIDs of immunizations not restored: %s +messageCountSamplesNotDeleted = %s samples not deleted. UUIDs of samples not deleted: %s messageCountSamplesNotRestored = %s samples not restored. UUIDs of samples not restored: %s +messageCountTasksNotDeleted = %s tasks not deleted. UUIDs of travel entries not deleted: %s +messageCountTravelEntriesNotDeleted = %s travel entries not deleted. UUIDs of travel entries not deleted: %s messageCountTravelEntriesNotRestored = %s travel entries not restored. UUIDs of travel entries not restored: %s -messageCountEventsNotDeleted = %s events not deleted. Event Ids not deleted: %s -messageEventsNotDeletedReason = No events that contain event participants linked will be deleted. Please remove the events participants from the event in order to be able to delete it. -messageCountEventsNotDeletedExternalSurveillanceTool=%s events not deleted due to the reporting tool communication. Event Ids not deleted: %s -messageEventsNotDeletedReasonExternalSurveillanceTool=Some events were not deleted because the communication with the reporting tool failed. +messageCountVisitsNotDeleted = %s visits not deleted. UUIDs of visits not deleted: %s +messageCountEventsNotDeleted = %s events not deleted. UUIDs of events not deleted: %s +messageEventsNotDeletedExternalReason = The events mentioned in the above list of UUIDs could not be deleted because the communication with the reporting tool failed. +messageEventsNotDeletedLinkedEntitiesReason = No events that contain event participants linked will be deleted. Please remove the event participants from the event in order to be able to delete it. messageExportFailed = There was an error preventing the data to be exported. Please contact an admin and inform them about this issue. messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved @@ -1145,6 +1174,7 @@ messageImportSuccessful = Import successful!
All rows have been impor messageUploadSuccessful = Upload successful! You can now close this window. messageIncompleteGpsCoordinates = GPS coordinates are incomplete messageExternalMessagesAssigned = The assignee has been changed for all selected messages +messageExternalMessagesNotDeleted = The external messages mentioned in the above list of UUIDs could not be deleted. messageLoginFailed = Please check your username and password and try again messageMissingCases = Please generate some cases before generating contacts messageMissingDateFilter = Please fill in both date filter fields @@ -1156,6 +1186,7 @@ messageNoContactsSelected = You have not selected any contacts messageNoCsvFile = You have not selected a file to upload. Please select a .csv file containing the data you want to import from your computer. messageNoDocumentTemplateUploadFile = You have not selected a file to upload. Please select a .docx template file you want to import from your computer. messageNoDocumentUploadFile = You have not selected a file to upload. Please select a file you want to import from your computer. +messageNoEligibleEventForDeletionSelected = None of the selected events are eligible for deletion messageNoEnvironmentsSelected = You have not selected any environments messageNoEventParticipantsSelected = You have not selected any event participants messageNoEventsSelected = You have not selected any events @@ -1188,7 +1219,8 @@ messageRelatedSampleFound = The sample referenced in this lab message seems to a messageRelatedSampleAndLabMessagesFound = A lab message with the same report ID was already processed. It is related to a sample also referenced in this lab message.
Do you want to directly open that sample? messageSampleErrors = There are errors in the sample form. Please fix them and save the sample before referring it to another laboratory. messageSampleSaved = Sample data saved -messageSamplesDeleted = All selected samples have been deleted +messageSamplesNotDeleted = The samples mentioned in the above list of UUIDs could not be deleted. +messageSamplesDeleted = All selected eligible samples have been deleted messageSpecifyColumnAttribute = Please specify the column attribute you have chosen for the visualization messageSpecifyFilterAttributes = Please specify all selected filter attributes and sub attributes messageSpecifyRowAttribute = Please specify the row attribute you have chosen for the visualization @@ -1196,15 +1228,17 @@ messageSymptomsHint = Please tick an answer for ALL symptoms indicating if th messageSymptomsVisitHint = Please tick an answer for ALL symptoms indicating if they were present at the time of this visit: messageTaskArchived = The task has been archived messageTasksEdited = All tasks have been edited +messageTasksNotDeleted = The tasks mentioned in the above list of UUIDs could not be deleted. messageTaskDearchived = The task has been de-archived -messageTasksDeleted = All selected tasks have been deleted +messageTasksDeleted = All selected eligible tasks have been deleted messageTemplateNotAvailable = The template file is not available. Please contact an admin and tell them about this issue. messageTravelEntryOutsideJurisdictionDeletionDenied = The travel entry outside user's jurisdiction cannot be deleted messageTravelEntrySaved = Travel entry data saved messageTravelEntryArchived = Travel entry has been archived messageTravelEntryDearchived = Travel entry has been de-archived messageTravelEntryPOEFilledBySystem = [System] Automatically filled point of entry -messageTravelEntriesDeleted = All selected travel entries have been deleted +messageTravelEntriesNotDeleted = The travel entries mentioned in the above list of UUIDs could not be deleted. +messageTravelEntriesDeleted = All selected eligible travel entries have been deleted messageTreatmentCreated = Treatment created messageTreatmentSaved = Treatment saved messageTreatmentsDeleted = All selected treatments have been deleted @@ -1215,7 +1249,8 @@ messageDiseaseNotSpecifiedInLabMessage = The disease of the external message cou messageUserRoleCombination = cannot be combined with messageUserRoleSaved = User role saved messageVaccinationOutsideJurisdictionDeletionDenied = The vaccination outside user's jurisdiction cannot be deleted -messageVisitsDeleted = All selected visits have been deleted +messageVisitsNotDeleted = The visits mentioned in the above list of UUIDs could not be deleted. +messageVisitsDeleted = All selected eligible visits have been deleted messageWrongFileType = Please provide a .csv file containing the data you want to import. It's recommended to use the import template file as a starting point. messageWrongTemplateFileType=For %s, please provide a .%s file. messageLineListingDisabled = Line listing has been disabled @@ -1307,8 +1342,8 @@ messageUserSyncSuccessful = Sync successful!
All users have been sync messageUserRightsExportFailed = Please contact an admin and notify them about this problem messageNoExternalMessagesSelected = You have not selected any messages messageExternalLabResultsAdapterNotFound = The external lab results adapter could not be found. This probably means you system is not configured correctly. Please contact you system administrator. -messageExternalMessagesDeleteProcessed = Only unprocessed messages can be deleted -messageExternalMessagesDeleted = All selected messages have been deleted +messageExternalMessagesEligibleForDeletion = Only unprocessed messages can be deleted +messageExternalMessagesDeleted = All selected eligible messages have been deleted messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignFacadeEjb.java index 9c494019135..872e2847942 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignFacadeEjb.java @@ -358,12 +358,24 @@ public void delete(String campaignUuid, DeletionDetails deletionDetails) { service.delete(service.getByUuid(campaignUuid), deletionDetails); } + @Override + @RightsAllowed(UserRight._CAMPAIGN_DELETE) + public List delete(List uuids, DeletionDetails deletionDetails) { + throw new NotImplementedException(); + } + @Override @RightsAllowed(UserRight._CAMPAIGN_DELETE) public void restore(String uuid) { super.restore(uuid); } + @Override + @RightsAllowed(UserRight._CAMPAIGN_DELETE) + public List restore(List uuids) { + throw new NotImplementedException(); + } + @Override protected void pseudonymizeDto(Campaign source, CampaignDto dto, Pseudonymizer pseudonymizer, boolean inJurisdiction) { // No pseudonymization for Campaign entities diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseFacadeEjb.java index 930b316858a..3263d628106 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseFacadeEjb.java @@ -2651,12 +2651,51 @@ public void delete(String caseUuid, DeletionDetails deletionDetails) deleteCase(caze, deletionDetails); } + @Override + @RightsAllowed(UserRight._CASE_DELETE) + public List delete(List uuids, DeletionDetails deletionDetails) { + List deletedCaseUuids = new ArrayList<>(); + List casesToBeDeleted = service.getByUuids(uuids); + if (casesToBeDeleted != null) { + casesToBeDeleted.forEach(caseToBeDeleted -> { + if (!caseToBeDeleted.isDeleted()) { + try { + deleteCase(caseToBeDeleted, deletionDetails); + deletedCaseUuids.add(caseToBeDeleted.getUuid()); + } catch (ExternalSurveillanceToolRuntimeException | SormasToSormasRuntimeException | AccessDeniedException e) { + logger.error("The case with uuid {} could not be deleted", caseToBeDeleted.getUuid(), e); + } + } + }); + } + return deletedCaseUuids; + } + @Override @RightsAllowed(UserRight._CASE_DELETE) public void restore(String uuid) { super.restore(uuid); } + @Override + @RightsAllowed(UserRight._CASE_DELETE) + public List restore(List uuids) { + List restoredCaseUuids = new ArrayList<>(); + List casesToBeRestored = caseService.getByUuids(uuids); + + if (casesToBeRestored != null) { + casesToBeRestored.forEach(caseToBeRestored -> { + try { + restore(caseToBeRestored.getUuid()); + restoredCaseUuids.add(caseToBeRestored.getUuid()); + } catch (Exception e) { + logger.error("The case with uuid {} could not be restored", caseToBeRestored.getUuid(), e); + } + }); + } + return restoredCaseUuids; + } + @Override @RightsAllowed(UserRight._CASE_DELETE) public void deleteWithContacts(String caseUuid, DeletionDetails deletionDetails) { @@ -2668,7 +2707,7 @@ public void deleteWithContacts(String caseUuid, DeletionDetails deletionDetails) } private void deleteCase(Case caze, DeletionDetails deletionDetails) - throws ExternalSurveillanceToolRuntimeException, SormasToSormasRuntimeException { + throws ExternalSurveillanceToolRuntimeException, SormasToSormasRuntimeException, AccessDeniedException { if (!caseService.inJurisdictionOrOwned(caze)) { throw new AccessDeniedException(I18nProperties.getString(Strings.messageCaseOutsideJurisdictionDeletionDenied)); @@ -2684,27 +2723,6 @@ private void deleteCase(Case caze, DeletionDetails deletionDetails) service.delete(caze, deletionDetails); } - @RightsAllowed(UserRight._CASE_DELETE) - @Override - public List deleteCases(List caseUuids, DeletionDetails deletionDetails) { - - List deletedCasesUuids = new ArrayList<>(); - List casesToBeDeleted = service.getByUuids(caseUuids); - if (casesToBeDeleted != null) { - casesToBeDeleted.forEach(caseToBeDeleted -> { - if (!caseToBeDeleted.isDeleted()) { - try { - deleteCase(caseToBeDeleted, deletionDetails); - deletedCasesUuids.add(caseToBeDeleted.getUuid()); - } catch (ExternalSurveillanceToolRuntimeException | SormasToSormasRuntimeException | AccessDeniedException e) { - logger.error("The case with uuid {} could not be deleted", caseToBeDeleted.getUuid(), e); - } - } - }); - } - return deletedCasesUuids; - } - @Override @RightsAllowed(UserRight._CASE_MERGE) public void deleteAsDuplicate(String caseUuid, String duplicateOfCaseUuid) { @@ -2727,7 +2745,7 @@ public void deleteCaseInExternalSurveillanceTool(Case caze) throws ExternalSurve // getByExternalId(caze) throws NPE (see #10820) so we use the service directly. // Can potentially be changed back once 10844 is done. List casesWithSameExternalId = service.getByExternalId(caze.getExternalID()); - if (casesWithSameExternalId != null && casesWithSameExternalId.size() == 1) { + if (casesWithSameExternalId != null && casesWithSameExternalId.size() == 1 && externalShareInfoService.isCaseShared(caze.getId())) { externalSurveillanceToolGatewayFacade.deleteCasesInternal(Collections.singletonList(toDto(caze))); } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactFacadeEjb.java index a23736f2deb..5bf6a3ffe30 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactFacadeEjb.java @@ -555,12 +555,52 @@ public void delete(String contactUuid, DeletionDetails deletionDetails) { deleteContact(contact, deletionDetails); } + @Override + @RightsAllowed(UserRight._CONTACT_DELETE) + public List delete(List uuids, DeletionDetails deletionDetails) { + List deletedContactUuids = new ArrayList<>(); + List contactsToBeDeleted = service.getByUuids(uuids); + if (contactsToBeDeleted != null) { + contactsToBeDeleted.forEach(contactToBeDeleted -> { + if (!contactToBeDeleted.isDeleted()) { + try { + deleteContact(contactToBeDeleted, deletionDetails); + deletedContactUuids.add(contactToBeDeleted.getUuid()); + } catch (AccessDeniedException e) { + logger.error("The contact with uuid {} could not be deleted", contactToBeDeleted.getUuid(), e); + } + } + }); + } + return deletedContactUuids; + } + @Override @RightsAllowed(UserRight._CONTACT_DELETE) public void restore(String uuid) { super.restore(uuid); } + @Override + @RightsAllowed(UserRight._CONTACT_DELETE) + public List restore(List uuids) { + List restoredContactUuids = new ArrayList<>(); + List contactsToBeRestored = contactService.getByUuids(uuids); + + if (contactsToBeRestored != null) { + contactsToBeRestored.forEach(contactToBeRestored -> { + try { + restore(contactToBeRestored.getUuid()); + restoredContactUuids.add(contactToBeRestored.getUuid()); + } catch (Exception e) { + logger.error("The contact with uuid:" + contactToBeRestored.getUuid() + "could not be restored"); + } + }); + } + + return restoredContactUuids; + } + private void deleteContact(Contact contact, DeletionDetails deletionDetails) { if (!contactService.inJurisdictionOrOwned(contact)) { @@ -579,26 +619,6 @@ private void deleteContact(Contact contact, DeletionDetails deletionDetails) { } } - @RightsAllowed(UserRight._CONTACT_DELETE) - public List deleteContacts(List contactUuids, DeletionDetails deletionDetails) { - List deletedContactUuids = new ArrayList<>(); - List contactsToBeDeleted = service.getByUuids(contactUuids); - if (contactsToBeDeleted != null) { - contactsToBeDeleted.forEach(contactToBeDeleted -> { - if (!contactToBeDeleted.isDeleted()) { - try { - deleteContact(contactToBeDeleted, deletionDetails); - deletedContactUuids.add(contactToBeDeleted.getUuid()); - } catch (AccessDeniedException e) { - logger.error("The contact with uuid {} could not be deleted", contactToBeDeleted.getUuid(), e); - } - } - }); - } - return deletedContactUuids; - - } - @Override @RightsAllowed(UserRight._CONTACT_ARCHIVE) public void archive(String entityUuid, Date endOfProcessingDate) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/EnvironmentFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/EnvironmentFacadeEjb.java index 0fb3c4633ce..1e43b379076 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/EnvironmentFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/EnvironmentFacadeEjb.java @@ -23,6 +23,8 @@ import javax.persistence.criteria.Root; import javax.persistence.criteria.Selection; +import org.apache.commons.lang3.NotImplementedException; + import de.symeda.sormas.api.common.CoreEntityType; import de.symeda.sormas.api.common.DeletionDetails; import de.symeda.sormas.api.environment.EnvironmentCriteria; @@ -30,12 +32,9 @@ import de.symeda.sormas.api.environment.EnvironmentFacade; import de.symeda.sormas.api.environment.EnvironmentIndexDto; import de.symeda.sormas.api.environment.EnvironmentReferenceDto; -import de.symeda.sormas.api.event.EventDto; import de.symeda.sormas.api.externalsurveillancetool.ExternalSurveillanceToolRuntimeException; import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.i18n.Strings; -import de.symeda.sormas.api.immunization.ImmunizationDto; -import de.symeda.sormas.api.person.PersonReferenceDto; import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.api.utils.AccessDeniedException; import de.symeda.sormas.api.utils.SortProperty; @@ -48,7 +47,6 @@ import de.symeda.sormas.backend.infrastructure.region.Region; import de.symeda.sormas.backend.location.Location; import de.symeda.sormas.backend.location.LocationFacadeEjb; -import de.symeda.sormas.backend.user.User; import de.symeda.sormas.backend.user.UserFacadeEjb; import de.symeda.sormas.backend.util.DtoHelper; import de.symeda.sormas.backend.util.IterableHelper; @@ -381,6 +379,18 @@ public List getArchivedUuidsSince(Date since) { return null; } + @RightsAllowed(UserRight._ENVIRONMENT_DELETE) + @Override + public List delete(List uuids, DeletionDetails deletionDetails) { + throw new NotImplementedException(); + } + + @Override + @RightsAllowed(UserRight._ENVIRONMENT_DELETE) + public List restore(List uuids) { + throw new NotImplementedException(); + } + @LocalBean @Stateless public static class EnvironmentFacadeEjbLocal extends EnvironmentFacadeEjb { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventFacadeEjb.java index 7e30fc90594..6f0eff6e2ae 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventFacadeEjb.java @@ -318,53 +318,40 @@ public void syncSharesAsync(ShareTreeCriteria criteria) { @Override @RightsAllowed(UserRight._EVENT_DELETE) - public void delete(String eventUuid, DeletionDetails deletionDetails) { + public void delete(String eventUuid, DeletionDetails deletionDetails) + throws ExternalSurveillanceToolRuntimeException, SormasToSormasRuntimeException { Event event = service.getByUuid(eventUuid); - - try { - sormasToSormasFacade.revokePendingShareRequests(event.getSormasToSormasShares(), true); - } catch (SormasToSormasException e) { - throw new SormasToSormasRuntimeException(e); - } - - try { - deleteEvent(event, deletionDetails); - } catch (ExternalSurveillanceToolException e) { - throw new ExternalSurveillanceToolRuntimeException(e.getMessage(), e.getErrorCode()); - } + deleteEvent(event, deletionDetails); } - @Override - @RightsAllowed(UserRight._EVENT_DELETE) - public void restore(String uuid) { - super.restore(uuid); - } + private void deleteEvent(Event event, DeletionDetails deletionDetails) + throws ExternalSurveillanceToolRuntimeException, SormasToSormasRuntimeException, AccessDeniedException { - private void deleteEvent(Event event, DeletionDetails deletionDetails) throws ExternalSurveillanceToolException { if (!eventService.inJurisdictionOrOwned(event)) { throw new AccessDeniedException(I18nProperties.getString(Strings.messageEventOutsideJurisdictionDeletionDenied)); } - if (event.getEventStatus() == EventStatus.CLUSTER - && externalSurveillanceToolFacade.isFeatureEnabled() - && externalShareInfoService.isEventShared(event.getId())) { - externalSurveillanceToolFacade.deleteEventsInternal(Collections.singletonList(toDto(event))); + try { + sormasToSormasFacade.revokePendingShareRequests(event.getSormasToSormasShares(), true); + } catch (SormasToSormasException e) { + throw new SormasToSormasRuntimeException(e); } service.delete(event, deletionDetails); } + @Override @RightsAllowed(UserRight._EVENT_DELETE) - public List deleteEvents(List eventUuids, DeletionDetails deletionDetails) { + public List delete(List uuids, DeletionDetails deletionDetails) { List deletedEventUuids = new ArrayList<>(); - List eventsToBeDeleted = service.getByUuids(eventUuids); + List eventsToBeDeleted = service.getByUuids(uuids); if (eventsToBeDeleted != null) { eventsToBeDeleted.forEach(eventToBeDeleted -> { if (!eventToBeDeleted.isDeleted()) { try { deleteEvent(eventToBeDeleted, deletionDetails); deletedEventUuids.add(eventToBeDeleted.getUuid()); - } catch (ExternalSurveillanceToolException e) { + } catch (ExternalSurveillanceToolRuntimeException | SormasToSormasRuntimeException | AccessDeniedException e) { logger.error("The event with uuid:" + eventToBeDeleted.getUuid() + "could not be deleted"); } } @@ -373,6 +360,31 @@ public List deleteEvents(List eventUuids, DeletionDetails deleti return deletedEventUuids; } + @Override + @RightsAllowed(UserRight._EVENT_DELETE) + public void restore(String uuid) { + super.restore(uuid); + } + + @Override + @RightsAllowed(UserRight._EVENT_DELETE) + public List restore(List uuids) { + List restoredEventsUuids = new ArrayList<>(); + List eventsToBeRestored = eventService.getByUuids(uuids); + + if (eventsToBeRestored != null) { + eventsToBeRestored.forEach(eventToBeRestored -> { + try { + restore(eventToBeRestored.getUuid()); + restoredEventsUuids.add(eventToBeRestored.getUuid()); + } catch (Exception e) { + logger.error("The event with uuid: " + eventToBeRestored.getUuid() + " could not be restored"); + } + }); + } + return restoredEventsUuids; + } + @RightsAllowed({ UserRight._EVENT_DELETE, UserRight._SYSTEM }) @@ -380,7 +392,11 @@ public void deleteEventInExternalSurveillanceTool(Event event) throws ExternalSu if (externalSurveillanceToolGatewayFacade.isFeatureEnabled() && StringUtils.isNotBlank(event.getExternalId())) { List eventsWithSameExternalId = service.getByExternalId(event.getExternalId()); - if (eventsWithSameExternalId != null && eventsWithSameExternalId.size() == 1) { + if (eventsWithSameExternalId != null + && eventsWithSameExternalId.size() == 1 + && event.getEventStatus() == EventStatus.CLUSTER + && externalSurveillanceToolFacade.isFeatureEnabled() + && externalShareInfoService.isEventShared(event.getId())) { externalSurveillanceToolGatewayFacade.deleteEventsInternal(Collections.singletonList(toDto(event))); } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java index 10c0a121a49..cc3e6d98e16 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java @@ -126,7 +126,6 @@ import de.symeda.sormas.backend.person.PersonQueryContext; import de.symeda.sormas.backend.person.PersonService; import de.symeda.sormas.backend.sample.Sample; -import de.symeda.sormas.backend.sample.SampleService; import de.symeda.sormas.backend.sormastosormas.origin.SormasToSormasOriginInfoFacadeEjb; import de.symeda.sormas.backend.sormastosormas.origin.SormasToSormasOriginInfoService; import de.symeda.sormas.backend.sormastosormas.share.outgoing.ShareInfoHelper; @@ -176,9 +175,6 @@ public class EventParticipantFacadeEjb @EJB private VaccinationService vaccinationService; - @EJB - private SampleService sampleService; - public EventParticipantFacadeEjb() { } @@ -513,12 +509,54 @@ public void delete(String uuid, DeletionDetails deletionDetails) throws External service.delete(eventParticipant, deletionDetails); } + @Override + @RightsAllowed(UserRight._EVENTPARTICIPANT_DELETE) + public List delete(List uuids, DeletionDetails deletionDetails) { + List deletedEventParticipantUuids = new ArrayList<>(); + List eventParticipantsToBeDeleted = service.getByUuids(uuids); + + if (eventParticipantsToBeDeleted != null) { + eventParticipantsToBeDeleted.forEach(eventParticipantToBeDeleted -> { + if (!eventParticipantToBeDeleted.isDeleted()) { + try { + delete(eventParticipantToBeDeleted.getUuid(), deletionDetails); + deletedEventParticipantUuids.add(eventParticipantToBeDeleted.getUuid()); + } catch (Exception e) { + logger.error("The event participant with uuid:" + eventParticipantToBeDeleted.getUuid() + "could not be deleted"); + } + } + }); + } + + return deletedEventParticipantUuids; + } + @Override @RightsAllowed(UserRight._EVENTPARTICIPANT_DELETE) public void restore(String uuid) { super.restore(uuid); } + @Override + @RightsAllowed(UserRight._EVENTPARTICIPANT_DELETE) + public List restore(List uuids) { + List restoredEventParticipantUuids = new ArrayList<>(); + List eventParticipantsToBeRestored = service.getByUuids(uuids); + + if (eventParticipantsToBeRestored != null) { + eventParticipantsToBeRestored.forEach(eventParticipantToBeRestored -> { + try { + restore(eventParticipantToBeRestored.getUuid()); + restoredEventParticipantUuids.add(eventParticipantToBeRestored.getUuid()); + } catch (Exception e) { + logger.error("The event participant with uuid:" + eventParticipantToBeRestored.getUuid() + "could not be restored"); + } + }); + } + + return restoredEventParticipantUuids; + } + @Override public List getIndexList( EventParticipantCriteria eventParticipantCriteria, diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageFacadeEjb.java index 7f1d43c6d39..d685909c876 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageFacadeEjb.java @@ -328,18 +328,27 @@ public ExternalMessageDto getByUuid(String uuid) { @Override @RightsAllowed(UserRight._EXTERNAL_MESSAGE_DELETE) - public void deleteExternalMessage(String uuid) { + public void delete(String uuid) { externalMessageService.deletePermanent(externalMessageService.getByUuid(uuid)); } @Override @RightsAllowed(UserRight._EXTERNAL_MESSAGE_DELETE) - public void deleteExternalMessages(List uuids) { - List externalMessages = externalMessageService.getByUuids(uuids); - for (ExternalMessage externalMessage : externalMessages) { - if (externalMessage.getStatus() != ExternalMessageStatus.PROCESSED) { - externalMessageService.deletePermanent(externalMessage); - } + public void delete(List uuids) { + List deletedExternalMessageUuids = new ArrayList<>(); + List externalMessagesToBeDeleted = externalMessageService.getByUuids(uuids); + + if (externalMessagesToBeDeleted != null) { + externalMessagesToBeDeleted.forEach(externalMessageToBeDeleted -> { + if (externalMessageToBeDeleted.getStatus() != ExternalMessageStatus.PROCESSED) { + try { + externalMessageService.deletePermanent(externalMessageToBeDeleted); + deletedExternalMessageUuids.add(externalMessageToBeDeleted.getUuid()); + } catch (Exception e) { + logger.error("The external message with uuid:" + externalMessageToBeDeleted.getUuid() + "could not be deleted"); + } + } + }); } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationFacadeEjb.java index 54befd1fee2..33159e3f45c 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationFacadeEjb.java @@ -307,12 +307,45 @@ public void delete(String uuid, DeletionDetails deletionDetails) { service.delete(immunization, deletionDetails); } + @Override + @RightsAllowed(UserRight._IMMUNIZATION_DELETE) + public List delete(List uuids, DeletionDetails deletionDetails) { + List deletedImmunizationUuids = new ArrayList<>(); + List immunizationsToBeDeleted = service.getByUuids(uuids); + if (immunizationsToBeDeleted != null) { + immunizationsToBeDeleted.forEach(immunizationToBeDeleted -> { + service.delete(immunizationToBeDeleted, deletionDetails); + deletedImmunizationUuids.add(immunizationToBeDeleted.getUuid()); + }); + } + return deletedImmunizationUuids; + } + @Override @RightsAllowed(UserRight._IMMUNIZATION_DELETE) public void restore(String uuid) { super.restore(uuid); } + @Override + @RightsAllowed(UserRight._IMMUNIZATION_DELETE) + public List restore(List uuids) { + List restoredImmunizationUuids = new ArrayList<>(); + List immunizationsToBeRestored = service.getByUuids(uuids); + + if (immunizationsToBeRestored != null) { + immunizationsToBeRestored.forEach(immunizationToBeRestored -> { + try { + service.restore(immunizationToBeRestored); + restoredImmunizationUuids.add(immunizationToBeRestored.getUuid()); + } catch (Exception e) { + logger.error("The immunization with uuid:" + immunizationToBeRestored.getUuid() + "could not be restored"); + } + }); + } + return restoredImmunizationUuids; + } + @Override public List getSimilarImmunizations(ImmunizationSimilarityCriteria criteria) { return service.getSimilarImmunizations(criteria).stream().map(result -> { @@ -458,19 +491,6 @@ public Page getIndexPage( return new Page<>(immunizationIndexList, offset, size, totalElementCount); } - @RightsAllowed(UserRight._IMMUNIZATION_DELETE) - public List deleteImmunizations(List immunizationUuids, DeletionDetails deletionDetails) { - List deletedImmunizationUuids = new ArrayList<>(); - List immunizationsToBeDeleted = service.getByUuids(immunizationUuids); - if (immunizationsToBeDeleted != null) { - immunizationsToBeDeleted.forEach(immunizationToBeDeleted -> { - service.delete(immunizationToBeDeleted, deletionDetails); - deletedImmunizationUuids.add(immunizationToBeDeleted.getUuid()); - }); - } - return deletedImmunizationUuids; - } - @Override protected ImmunizationReferenceDto toRefDto(Immunization immunization) { return toReferenceDto(immunization); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleFacadeEjb.java index 55221bd8bdf..3f16fff7762 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleFacadeEjb.java @@ -763,6 +763,25 @@ public void delete(String sampleUuid, DeletionDetails deletionDetails) { handleAssociatedEntityChanges(sample, true); } + @Override + @RightsAllowed(UserRight._SAMPLE_DELETE) + public List restore(List uuids) { + List restoredSampleUuids = new ArrayList<>(); + List samplesToBeRestored = sampleService.getByUuids(uuids); + + if (samplesToBeRestored != null) { + samplesToBeRestored.forEach(sampleToBeRestored -> { + try { + restore(sampleToBeRestored.getUuid()); + restoredSampleUuids.add(sampleToBeRestored.getUuid()); + } catch (Exception e) { + logger.error("The sample with uuid:" + sampleToBeRestored.getUuid() + "could not be restored"); + } + }); + } + return restoredSampleUuids; + } + @Override @RightsAllowed(UserRight._SAMPLE_DELETE) public void restore(String sampleUuid) { @@ -772,12 +791,13 @@ public void restore(String sampleUuid) { @Override @RightsAllowed(UserRight._SAMPLE_DELETE) - public void deleteAllSamples(List sampleUuids, DeletionDetails deletionDetails) { + public List delete(List sampleUuids, DeletionDetails deletionDetails) { long startTime = DateHelper.startTime(); IterableHelper .executeBatched(sampleUuids, DELETED_BATCH_SIZE, batchedSampleUuids -> sampleService.deleteAll(batchedSampleUuids, deletionDetails)); logger.debug("deleteAllSamples(sampleUuids) finished. samplesCount = {}, {}ms", sampleUuids.size(), DateHelper.durationMillies(startTime)); + return sampleUuids; } @RightsAllowed(UserRight._SAMPLE_DELETE) diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskFacadeEjb.java index 5fd89c038a7..b59d34398ec 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskFacadeEjb.java @@ -914,19 +914,34 @@ public TaskDto getByUuid(String uuid) { @Override @RightsAllowed(UserRight._TASK_DELETE) - public void deleteTask(TaskDto taskDto) { - Task task = taskService.getByUuid(taskDto.getUuid()); + public void delete(String uuid) { + if (!userService.hasRight(UserRight.TASK_DELETE)) { + throw new UnsupportedOperationException(String.format("User %s is not allowed to delete tasks.", userService.getCurrentUser().getUuid())); + } + + Task task = taskService.getByUuid(uuid); taskService.deletePermanent(task); } + @Override + @RightsAllowed(UserRight._TASK_DELETE) + public void delete(List uuids) { + deleteTasks(uuids); + } + @RightsAllowed(UserRight._TASK_DELETE) public List deleteTasks(List tasksUuids) { List deletedTaskUuids = new ArrayList<>(); List tasksToBeDeleted = taskService.getByUuids(tasksUuids); + if (tasksToBeDeleted != null) { tasksToBeDeleted.forEach(taskToBeDeleted -> { - taskService.deletePermanent(taskToBeDeleted); - deletedTaskUuids.add(taskToBeDeleted.getUuid()); + try { + taskService.deletePermanent(taskToBeDeleted); + deletedTaskUuids.add(taskToBeDeleted.getUuid()); + } catch (Exception e) { + logger.error("The task with uuid:" + taskToBeDeleted.getUuid() + "could not be deleted"); + } }); } return deletedTaskUuids; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/TravelEntryFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/TravelEntryFacadeEjb.java index ee3248c3d50..a29e7c7a227 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/TravelEntryFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/TravelEntryFacadeEjb.java @@ -2,6 +2,7 @@ import java.sql.Timestamp; import java.time.LocalDate; +import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -19,6 +20,8 @@ import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import de.symeda.sormas.api.common.CoreEntityType; import de.symeda.sormas.api.common.DeletionDetails; @@ -67,6 +70,8 @@ public class TravelEntryFacadeEjb extends AbstractCoreFacadeEjb implements TravelEntryFacade { + private final Logger logger = LoggerFactory.getLogger(getClass()); + @EJB private TravelEntryListService travelEntryListService; @EJB @@ -122,12 +127,54 @@ public void delete(String travelEntryUuid, DeletionDetails deletionDetails) { } } + @Override + @RightsAllowed(UserRight._TRAVEL_ENTRY_DELETE) + public List delete(List uuids, DeletionDetails deletionDetails) { + List deletedTravelEntryUuids = new ArrayList<>(); + List travelEntriesToBeDeleted = travelEntryService.getByUuids(uuids); + + if (travelEntriesToBeDeleted != null) { + travelEntriesToBeDeleted.forEach(travelEntryToBeDeleted -> { + if (!travelEntryToBeDeleted.isDeleted()) { + try { + delete(travelEntryToBeDeleted.getUuid(), deletionDetails); + deletedTravelEntryUuids.add(travelEntryToBeDeleted.getUuid()); + } catch (Exception e) { + logger.error("The travel entry with uuid:" + travelEntryToBeDeleted.getUuid() + "could not be deleted"); + } + } + }); + } + + return deletedTravelEntryUuids; + } + @Override @RightsAllowed(UserRight._TRAVEL_ENTRY_DELETE) public void restore(String uuid) { super.restore(uuid); } + @Override + @RightsAllowed(UserRight._TRAVEL_ENTRY_DELETE) + public List restore(List uuids) { + List restoredTravelEntryUuids = new ArrayList<>(); + List travelEntriesToBeRestored = travelEntryService.getByUuids(uuids); + + if (travelEntriesToBeRestored != null) { + travelEntriesToBeRestored.forEach(travelEntryToBeRestored -> { + try { + restore(travelEntryToBeRestored.getUuid()); + restoredTravelEntryUuids.add(travelEntryToBeRestored.getUuid()); + } catch (Exception e) { + logger.error("The travel entry with uuid:" + travelEntryToBeRestored.getUuid() + "could not be restored"); + } + }); + } + + return restoredTravelEntryUuids; + } + @Override public List getDeaContentOfLastTravelEntry() { final TravelEntry lastTravelEntry = service.getLastTravelEntry(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitFacadeEjb.java index 81bab2147c9..1a0993899fd 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitFacadeEjb.java @@ -115,6 +115,8 @@ public class VisitFacadeEjb extends AbstractBaseEjb uuids) { + deleteVisits(uuids); + } + + @Override + @RightsAllowed(UserRight._VISIT_DELETE) + public List deleteVisits(List uuids) { + List deletedVisitUuids = new ArrayList<>(); + List visitsToBeDeleted = visitService.getByUuids(uuids); + + if (visitsToBeDeleted != null) { + visitsToBeDeleted.forEach(visitToBeDeleted -> { + try { + delete(visitToBeDeleted.getUuid()); + deletedVisitUuids.add(visitToBeDeleted.getUuid()); + } catch (Exception e) { + logger.error("The visit with uuid:" + visitToBeDeleted.getUuid() + "could not be deleted"); + } + }); + } + + return deletedVisitUuids; + } + @Override public List getIndexList(VisitCriteria visitCriteria, Integer first, Integer max, List sortProperties) { diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/ArchitectureTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/ArchitectureTest.java index 21285b8aae2..795a9ab825d 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/ArchitectureTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/ArchitectureTest.java @@ -276,8 +276,7 @@ public void testExternalMessageFacadeEjbAuthorization(JavaClasses classes) { "getExternalMessagesAdapterVersion", "fetchAndSaveExternalMessages", "bulkAssignExternalMessages", - "deleteExternalMessage", - "deleteExternalMessages"), + "delete"), classes); } diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbTest.java index a0ff7d11f43..cb37ede80d1 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbTest.java @@ -2831,13 +2831,13 @@ public void testDeleteCasesOutsideJurisdiction() { loginWith(surveillanceOfficer); - List deleteUuids = getCaseFacade().deleteCases(caseUuidList, new DeletionDetails(DeletionReason.OTHER_REASON, "test reason")); + List deleteUuids = getCaseFacade().delete(caseUuidList, new DeletionDetails(DeletionReason.OTHER_REASON, "test reason")); assertEquals(1, deleteUuids.size()); assertEquals(caze1.getUuid(), deleteUuids.get(0)); loginWith(nationalUser); - getCaseFacade().deleteCases(caseUuidList, new DeletionDetails(DeletionReason.OTHER_REASON, "test reason")); + getCaseFacade().delete(caseUuidList, new DeletionDetails(DeletionReason.OTHER_REASON, "test reason")); assertEquals(0, getCaseFacade().getAllActiveUuids().size()); } diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/contact/ContactFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/contact/ContactFacadeEjbTest.java index ca4cf0c601b..8db4004aa6c 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/contact/ContactFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/contact/ContactFacadeEjbTest.java @@ -362,12 +362,12 @@ public void testDeleteContactsOutsideJurisdiction() { UserDto user = creator.createSurveillanceOfficer(rdcf1); loginWith(user); List deleteUuids = - getContactFacade().deleteContacts(contactUuidList, new DeletionDetails(DeletionReason.OTHER_REASON, "test reason")); + getContactFacade().delete(contactUuidList, new DeletionDetails(DeletionReason.OTHER_REASON, "test reason")); assertEquals(1, deleteUuids.size()); assertEquals(contact1.getUuid(), deleteUuids.get(0)); loginWith(creatorUser); - getContactFacade().deleteContacts(contactUuidList, new DeletionDetails(DeletionReason.OTHER_REASON, "test reason")); + getContactFacade().delete(contactUuidList, new DeletionDetails(DeletionReason.OTHER_REASON, "test reason")); assertEquals(0, getContactFacade().getAllActiveUuids().size()); } diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/externalmessage/ExternalMessageServiceTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/externalmessage/ExternalMessageServiceTest.java index 70150f8b710..15132195023 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/externalmessage/ExternalMessageServiceTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/externalmessage/ExternalMessageServiceTest.java @@ -55,7 +55,7 @@ public void testGetForSample() throws InterruptedException { ExternalMessageDto labMessage1Deleted = creator.createLabMessageWithTestReport(sampleReference1); labMessage1Deleted.setChangeDate(new Date()); getExternalMessageFacade().save(labMessage1Deleted); - getExternalMessageFacade().deleteExternalMessage(labMessage1Deleted.getUuid()); + getExternalMessageFacade().delete(labMessage1Deleted.getUuid()); SampleDto sample2 = creator.createSample(caze.toReference(), sampleDate, sampleDate, user.toReference(), SampleMaterial.BLOOD, rdcf.facility); SampleReferenceDto sampleReference2 = sample2.toReference(); @@ -181,7 +181,7 @@ public void testLabMessagePermanentDeletion() { ExternalMessageDto labMessage = creator.createLabMessageWithTestReport(null); - getExternalMessageFacade().deleteExternalMessage(labMessage.getUuid()); + getExternalMessageFacade().delete(labMessage.getUuid()); assertEquals(0, getExternalMessageService().count()); assertEquals(0, getSampleReportService().count()); diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/sample/SampleFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/sample/SampleFacadeEjbTest.java index 89453f30a39..490d765c1dc 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/sample/SampleFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/sample/SampleFacadeEjbTest.java @@ -425,9 +425,8 @@ public void testAllSamplesDeletionWithOneAdditionalTest() { assertNotNull(getPathogenTestFacade().getByUuid(firstSamplePathogenTest.getUuid())); assertNotNull(getAdditionalTestFacade().getByUuid(firstSampleAdditionalTest.getUuid())); - getSampleFacade().deleteAllSamples( - Arrays.asList(firstSample.getUuid(), secondSample.getUuid()), - new DeletionDetails(DeletionReason.OTHER_REASON, "test reason")); + getSampleFacade() + .delete(Arrays.asList(firstSample.getUuid(), secondSample.getUuid()), new DeletionDetails(DeletionReason.OTHER_REASON, "test reason")); // Sample and pathogen test should be marked as deleted, additional test should be deleted List sampleUuids = getSampleFacade().getDeletedUuidsSince(since); @@ -487,9 +486,8 @@ public void testAllSamplesDeletionWithMultipleAdditionalTest() { assertNotNull(getAdditionalTestFacade().getByUuid(secondSampleAdditionalTest.getUuid())); assertNotNull(getAdditionalTestFacade().getByUuid(thirdSampleAdditionalTest.getUuid())); - getSampleFacade().deleteAllSamples( - Arrays.asList(thirdSample.getUuid(), forthSample.getUuid()), - new DeletionDetails(DeletionReason.OTHER_REASON, "test reason")); + getSampleFacade() + .delete(Arrays.asList(thirdSample.getUuid(), forthSample.getUuid()), new DeletionDetails(DeletionReason.OTHER_REASON, "test reason")); // Sample and pathogen test should be marked as deleted, additional tests should be deleted List sampleUuids = getSampleFacade().getDeletedUuidsSince(since); diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/task/TaskFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/task/TaskFacadeEjbTest.java index f2940964dfb..050e7004264 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/task/TaskFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/task/TaskFacadeEjbTest.java @@ -134,7 +134,7 @@ public void testSampleDeletion() { // Database should contain the created task assertNotNull(getTaskFacade().getByUuid(task.getUuid())); - getTaskFacade().deleteTask(task); + getTaskFacade().delete(task.getUuid()); // Database should not contain the created task assertNull(getTaskFacade().getByUuid(task.getUuid())); diff --git a/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/CaseResource.java b/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/CaseResource.java index 3e3bf707500..9240aac933c 100644 --- a/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/CaseResource.java +++ b/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/CaseResource.java @@ -211,7 +211,7 @@ public CaseDataDto postUpdate(@PathParam("uuid") String uuid, JsonNode caseDataD @POST @Path("/delete") public List delete(List uuids) { - return FacadeProvider.getCaseFacade().deleteCases(uuids, new DeletionDetails(DeletionReason.OTHER_REASON, "Deleted via ReST call")); + return FacadeProvider.getCaseFacade().delete(uuids, new DeletionDetails(DeletionReason.OTHER_REASON, "Deleted via ReST call")); } @POST diff --git a/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/ContactResource.java b/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/ContactResource.java index 91fa87228d9..e133c896b1e 100644 --- a/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/ContactResource.java +++ b/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/ContactResource.java @@ -149,7 +149,7 @@ public Response updateExternalData(@Valid List externalData) { @POST @Path("/delete") public List delete(List uuids) { - return FacadeProvider.getContactFacade().deleteContacts(uuids, new DeletionDetails(DeletionReason.OTHER_REASON, "Deleted via ReST call")); + return FacadeProvider.getContactFacade().delete(uuids, new DeletionDetails(DeletionReason.OTHER_REASON, "Deleted via ReST call")); } @GET diff --git a/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/EventResource.java b/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/EventResource.java index 83db348d48d..468403fe52b 100644 --- a/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/EventResource.java +++ b/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/EventResource.java @@ -137,7 +137,7 @@ public Response updateExternalData(List externalData) { @POST @Path("/delete") public List delete(List uuids) { - return FacadeProvider.getEventFacade().deleteEvents(uuids, new DeletionDetails(DeletionReason.OTHER_REASON, "Deleted via ReST call")); + return FacadeProvider.getEventFacade().delete(uuids, new DeletionDetails(DeletionReason.OTHER_REASON, "Deleted via ReST call")); } @POST diff --git a/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/ImmunizationResource.java b/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/ImmunizationResource.java index e6b78e1d3d9..65f9df9702d 100644 --- a/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/ImmunizationResource.java +++ b/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/ImmunizationResource.java @@ -124,8 +124,7 @@ public Page getIndexList( @POST @Path("/delete") public List delete(List uuids) { - return FacadeProvider.getImmunizationFacade() - .deleteImmunizations(uuids, new DeletionDetails(DeletionReason.OTHER_REASON, "Deleted via ReST call")); + return FacadeProvider.getImmunizationFacade().delete(uuids, new DeletionDetails(DeletionReason.OTHER_REASON, "Deleted via ReST call")); } @POST diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/ControllerProvider.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/ControllerProvider.java index 446efda9b7d..f36f51e1590 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/ControllerProvider.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/ControllerProvider.java @@ -49,6 +49,7 @@ import de.symeda.sormas.ui.utils.ArchivingController; import de.symeda.sormas.ui.utils.BaseControllerProvider; import de.symeda.sormas.ui.utils.DeleteRestoreController; +import de.symeda.sormas.ui.utils.PermanentDeleteController; import de.symeda.sormas.ui.vaccination.VaccinationController; import de.symeda.sormas.ui.visit.VisitController; @@ -87,6 +88,7 @@ public class ControllerProvider extends BaseControllerProvider { private final ArchivingController archivingController; private final DeleteRestoreController deleteRestoreController; private final EnvironmentController environmentController; + private final PermanentDeleteController permanentDeleteController; public ControllerProvider() { super(); @@ -124,6 +126,7 @@ public ControllerProvider() { archivingController = new ArchivingController(); deleteRestoreController = new DeleteRestoreController(); environmentController = new EnvironmentController(); + permanentDeleteController = new PermanentDeleteController(); } protected static ControllerProvider get() { @@ -261,4 +264,7 @@ public static DeleteRestoreController getDeleteRestoreController() { public static EnvironmentController getEnvironmentController() { return get().environmentController; } + public static PermanentDeleteController getPermanentDeleteController() { + return get().permanentDeleteController; + } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseContactsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseContactsView.java index 4f76337cd3a..9352055934d 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseContactsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseContactsView.java @@ -56,6 +56,7 @@ import de.symeda.sormas.ui.ControllerProvider; import de.symeda.sormas.ui.UserProvider; import de.symeda.sormas.ui.ViewModelProviders; +import de.symeda.sormas.ui.contact.AbstractContactGrid; import de.symeda.sormas.ui.contact.ContactGrid; import de.symeda.sormas.ui.contact.importer.CaseContactsImportLayout; import de.symeda.sormas.ui.utils.ButtonHelper; @@ -262,7 +263,7 @@ public HorizontalLayout createStatusFilterBar() { }), new MenuBarHelper.MenuBarItem(I18nProperties.getCaption(Captions.bulkDelete), VaadinIcons.TRASH, selectedItem -> { ControllerProvider.getContactController() - .deleteAllSelectedItems(grid.asMultiSelect().getSelectedItems(), () -> navigateTo(criteria)); + .deleteAllSelectedItems(grid.asMultiSelect().getSelectedItems(), (AbstractContactGrid) grid); })); statusFilterLayout.addComponent(bulkOperationsDropdown); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java index 4b51f517efd..4708863cdc9 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java @@ -105,7 +105,6 @@ import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.api.utils.DataHelper; import de.symeda.sormas.api.utils.DateHelper; -import de.symeda.sormas.api.utils.HtmlHelper; import de.symeda.sormas.api.utils.ValidationRuntimeException; import de.symeda.sormas.api.utils.YesNoUnknown; import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; @@ -136,9 +135,8 @@ import de.symeda.sormas.ui.utils.BulkOperationHandler; import de.symeda.sormas.ui.utils.ButtonHelper; import de.symeda.sormas.ui.utils.CommitDiscardWrapperComponent; -import de.symeda.sormas.ui.utils.CoreEntityRestoreMessages; import de.symeda.sormas.ui.utils.CssStyles; -import de.symeda.sormas.ui.utils.DeletableUtils; +import de.symeda.sormas.ui.utils.DeleteRestoreHandlers; import de.symeda.sormas.ui.utils.DetailSubComponentWrapper; import de.symeda.sormas.ui.utils.NullableOptionGroup; import de.symeda.sormas.ui.utils.VaadinUiUtil; @@ -1044,30 +1042,34 @@ public void showBulkCaseDataEditComponent(Collection 500, e -> BulkOperationHandler. forBulkEdit() .doBulkOperation( - selectedEntries -> caseFacade.saveBulkEditWithFacilities( + selectedEntries -> caseFacade.saveBulkEditWithFacilities( + selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList()), + updatedBulkEditData, + diseaseChange, + classificationChange, + investigationStatusChange, + outcomeChange, + surveillanceOfficerChange, + e), + selectedCasesCpy, + null, + null, + bulkOperationCallback(caseGrid, popupWindow))); + } else { + BulkOperationHandler. forBulkEdit() + .doBulkOperation( + selectedEntries -> caseFacade.saveBulkCase( selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList()), updatedBulkEditData, diseaseChange, classificationChange, investigationStatusChange, outcomeChange, - surveillanceOfficerChange, - e), + surveillanceOfficerChange), selectedCasesCpy, - bulkOperationCallback(caseGrid, popupWindow))); - } else { - BulkOperationHandler. forBulkEdit() - .doBulkOperation( - selectedEntries -> caseFacade.saveBulkCase( - selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList()), - updatedBulkEditData, - diseaseChange, - classificationChange, - investigationStatusChange, - outcomeChange, - surveillanceOfficerChange), - selectedCasesCpy, - bulkOperationCallback(caseGrid, popupWindow)); + null, + null, + bulkOperationCallback(caseGrid, popupWindow)); } }); @@ -1546,63 +1548,16 @@ public void openClassificationRulesPopup(DiseaseClassificationCriteriaDto diseas popupWindow.setCaption(I18nProperties.getString(Strings.classificationRulesFor) + " " + diseaseCriteria.getDisease().toString()); } - public void deleteAllSelectedItems(Collection selectedRows, Runnable callback) { + public void deleteAllSelectedItems(Collection selectedRows, AbstractCaseGrid caseGrid) { + + ControllerProvider.getDeleteRestoreController() + .deleteAllSelectedItems(selectedRows, null, null, DeleteRestoreHandlers.forCase(), bulkOperationCallback(caseGrid, null)); - if (selectedRows.size() == 0) { - new Notification( - I18nProperties.getString(Strings.headingNoCasesSelected), - I18nProperties.getString(Strings.messageNoCasesSelected), - Type.WARNING_MESSAGE, - false).show(Page.getCurrent()); - } else { - DeletableUtils.showDeleteWithReasonPopup( - String.format(I18nProperties.getString(Strings.confirmationDeleteCases), selectedRows.size()) + "
" - + getDeleteConfirmationDetails(selectedRows.stream().map(CaseIndexDto::getUuid).collect(Collectors.toList())), - (deleteDetails) -> { - int countNotDeletedCases = 0; - StringBuilder nonDeletableCases = new StringBuilder(); - for (CaseIndexDto selectedRow : selectedRows) { - try { - FacadeProvider.getCaseFacade().delete(selectedRow.getUuid(), deleteDetails); - } catch (ExternalSurveillanceToolRuntimeException e) { - countNotDeletedCases++; - nonDeletableCases.append(selectedRow.getUuid(), 0, 6).append(", "); - } - } - if (nonDeletableCases.length() > 0) { - nonDeletableCases = new StringBuilder(" " + nonDeletableCases.substring(0, nonDeletableCases.length() - 2) + ". "); - } - callback.run(); - if (countNotDeletedCases == 0) { - new Notification( - I18nProperties.getString(Strings.headingCasesDeleted), - I18nProperties.getString(Strings.messageCasesDeleted), - Type.HUMANIZED_MESSAGE, - false).show(Page.getCurrent()); - } else { - Window response = VaadinUiUtil.showSimplePopupWindow( - I18nProperties.getString(Strings.headingSomeCasesNotDeleted), - String.format( - "%1s

%2s", - String.format( - I18nProperties.getString(Strings.messageCountCasesNotDeleted), - String.format("%s", countNotDeletedCases), - String.format("%s", HtmlHelper.cleanHtml(nonDeletableCases.toString()))), - I18nProperties.getString(Strings.messageCasesNotDeletedReasonExternalSurveillanceTool)), - ContentMode.HTML); - response.setWidth(600, Sizeable.Unit.PIXELS); - } - }); - } } - public void restoreSelectedCases(Collection selectedRows, Runnable callback) { + public void restoreSelectedCases(Collection selectedRows, AbstractCaseGrid caseGrid) { ControllerProvider.getDeleteRestoreController() - .restoreSelectedItems( - selectedRows.stream().map(CaseIndexDto::getUuid).collect(Collectors.toList()), - FacadeProvider.getCaseFacade(), - CoreEntityRestoreMessages.CASE, - callback); + .restoreSelectedItems(selectedRows, DeleteRestoreHandlers.forCase(), bulkOperationCallback(caseGrid, null)); } public void sendSmsToAllSelectedItems(Collection selectedRows, Runnable callback) { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseVisitsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseVisitsView.java index 745fcf73a59..b620971b4cc 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseVisitsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseVisitsView.java @@ -83,7 +83,7 @@ public HorizontalLayout createTopBar() { Captions.bulkActions, new MenuBarHelper.MenuBarItem(I18nProperties.getCaption(Captions.bulkDelete), VaadinIcons.TRASH, selectedItem -> { ControllerProvider.getVisitController() - .deleteAllSelectedItems(grid.asMultiSelect().getSelectedItems(), () -> navigateTo(criteria)); + .deleteAllSelectedItems(grid.asMultiSelect().getSelectedItems(), grid, () -> navigateTo(criteria)); })); topLayout.addComponent(bulkOperationsDropdown); topLayout.setComponentAlignment(bulkOperationsDropdown, Alignment.MIDDLE_RIGHT); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasesView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasesView.java index aa25a7d16a4..6e54c4e7a4b 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasesView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasesView.java @@ -723,14 +723,14 @@ public HorizontalLayout createStatusFilterBar() { if (criteria.getRelevanceStatus() != EntityRelevanceStatus.DELETED) { menuBarItems.add(new MenuBarHelper.MenuBarItem(I18nProperties.getCaption(Captions.bulkDelete), VaadinIcons.TRASH, mi -> { grid.bulkActionHandler( - items -> ControllerProvider.getCaseController().deleteAllSelectedItems(items, () -> navigateTo(criteria)), + items -> ControllerProvider.getCaseController().deleteAllSelectedItems(items, (AbstractCaseGrid) grid), true); }, hasBulkOperationsRight)); } else { menuBarItems .add(new MenuBarHelper.MenuBarItem(I18nProperties.getCaption(Captions.bulkRestore), VaadinIcons.ARROW_BACKWARD, mi -> { grid.bulkActionHandler( - items -> ControllerProvider.getCaseController().restoreSelectedCases(items, () -> navigateTo(criteria)), + items -> ControllerProvider.getCaseController().restoreSelectedCases(items, (AbstractCaseGrid) grid), true); }, hasBulkOperationsRight)); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactController.java index 1cd1a418ced..45315ab2e4d 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactController.java @@ -90,9 +90,9 @@ import de.symeda.sormas.ui.utils.ArchiveHandlers; import de.symeda.sormas.ui.utils.BulkOperationHandler; import de.symeda.sormas.ui.utils.CommitDiscardWrapperComponent; -import de.symeda.sormas.ui.utils.CoreEntityRestoreMessages; import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.DeletableUtils; +import de.symeda.sormas.ui.utils.DeleteRestoreHandlers; import de.symeda.sormas.ui.utils.VaadinUiUtil; import de.symeda.sormas.ui.utils.ViewMode; import de.symeda.sormas.ui.utils.components.automaticdeletion.DeletionLabel; @@ -765,13 +765,15 @@ public void showBulkContactDataEditComponent( List selectedContactsCpy = new ArrayList<>(selectedContacts); BulkOperationHandler. forBulkEdit() .doBulkOperation( - selectedEntries -> contactFacade.saveBulkContacts( - selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList()), - updatedBulkEditData, - classificationChange, - contactOfficerChange), - selectedContactsCpy, - bulkOperationCallback(caseUuid, contactGrid, popupWindow)); + selectedEntries -> contactFacade.saveBulkContacts( + selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList()), + updatedBulkEditData, + classificationChange, + contactOfficerChange), + selectedContactsCpy, + null, + null, + bulkOperationCallback(caseUuid, contactGrid, popupWindow)); }); editView.addDiscardListener(popupWindow::close); @@ -799,41 +801,16 @@ private Consumer> bulkOperationCallback(String caseUuid, A }; } - public void deleteAllSelectedItems(Collection selectedRows, Runnable callback) { - if (selectedRows.size() == 0) { - new Notification( - I18nProperties.getString(Strings.headingNoContactsSelected), - I18nProperties.getString(Strings.messageNoContactsSelected), - Type.WARNING_MESSAGE, - false).show(Page.getCurrent()); - } else { - DeletableUtils.showDeleteWithReasonPopup( - String.format( - I18nProperties.getString(Strings.confirmationDeleteContacts), - selectedRows.size(), - getDeleteConfirmationDetails(selectedRows.stream().map(ContactIndexDto::getUuid).collect(Collectors.toList()))), - (deleteDetails) -> { - for (ContactIndexDto selectedRow : selectedRows) { - FacadeProvider.getContactFacade().delete(selectedRow.getUuid(), deleteDetails); - } - callback.run(); - new Notification( - I18nProperties.getString(Strings.headingContactsDeleted), - I18nProperties.getString(Strings.messageContactsDeleted), - Type.HUMANIZED_MESSAGE, - false).show(Page.getCurrent()); - }); + public void deleteAllSelectedItems(Collection selectedRows, AbstractContactGrid contactGrid) { + + ControllerProvider.getDeleteRestoreController() + .deleteAllSelectedItems(selectedRows, null, null, DeleteRestoreHandlers.forContact(), bulkOperationCallback(null, contactGrid, null)); - } } - public void restoreSelectedContacts(Collection selectedRows, Runnable callback) { + public void restoreSelectedContacts(Collection selectedRows, AbstractContactGrid contactGrid) { ControllerProvider.getDeleteRestoreController() - .restoreSelectedItems( - selectedRows.stream().map(ContactIndexDto::getUuid).collect(Collectors.toList()), - FacadeProvider.getContactFacade(), - CoreEntityRestoreMessages.CONTACT, - callback); + .restoreSelectedItems(selectedRows, DeleteRestoreHandlers.forContact(), bulkOperationCallback(null, contactGrid, null)); } public void cancelFollowUpOfAllSelectedItems(Collection selectedRows, Runnable callback) { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactVisitsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactVisitsView.java index 73f2249075c..23143601a5b 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactVisitsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactVisitsView.java @@ -93,12 +93,8 @@ public HorizontalLayout createTopBar() { MenuBar bulkOperationsDropdown = MenuBarHelper.createDropDown( Captions.bulkActions, new MenuBarHelper.MenuBarItem(I18nProperties.getCaption(Captions.bulkDelete), VaadinIcons.TRASH, selectedItem -> { - ControllerProvider.getVisitController().deleteAllSelectedItems(grid.asMultiSelect().getSelectedItems(), new Runnable() { - - public void run() { - navigateTo(criteria); - } - }); + ControllerProvider.getVisitController() + .deleteAllSelectedItems(grid.asMultiSelect().getSelectedItems(), grid, () -> navigateTo(criteria)); })); topLayout.addComponent(bulkOperationsDropdown); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsView.java index 47566bafa42..e5ded699a96 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsView.java @@ -537,14 +537,14 @@ public HorizontalLayout createStatusFilterBar() { I18nProperties.getCaption(Captions.bulkDelete), VaadinIcons.TRASH, mi -> grid.bulkActionHandler( - items -> ControllerProvider.getContactController().deleteAllSelectedItems(items, () -> navigateTo(criteria)), + items -> ControllerProvider.getContactController().deleteAllSelectedItems(items, (AbstractContactGrid) grid), true), hasBulkOperationsRight) : new MenuBarHelper.MenuBarItem( I18nProperties.getCaption(Captions.bulkRestore), VaadinIcons.ARROW_BACKWARD, mi -> grid.bulkActionHandler( - items -> ControllerProvider.getContactController().restoreSelectedContacts(items, () -> navigateTo(criteria)), + items -> ControllerProvider.getContactController().restoreSelectedContacts(items, (AbstractContactGrid) grid), true), hasBulkOperationsRight), new MenuBarHelper.MenuBarItem( diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventController.java index 29725a299a3..e833404b4fe 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventController.java @@ -73,7 +73,6 @@ import de.symeda.sormas.api.user.UserDto; import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.api.utils.DataHelper; -import de.symeda.sormas.api.utils.HtmlHelper; import de.symeda.sormas.api.uuid.HasUuid; import de.symeda.sormas.ui.ControllerProvider; import de.symeda.sormas.ui.SormasUI; @@ -85,10 +84,9 @@ import de.symeda.sormas.ui.utils.ArchiveHandlers; import de.symeda.sormas.ui.utils.BulkOperationHandler; import de.symeda.sormas.ui.utils.CommitDiscardWrapperComponent; -import de.symeda.sormas.ui.utils.CoreEntityRestoreMessages; import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.DateFormatHelper; -import de.symeda.sormas.ui.utils.DeletableUtils; +import de.symeda.sormas.ui.utils.DeleteRestoreHandlers; import de.symeda.sormas.ui.utils.NotificationHelper; import de.symeda.sormas.ui.utils.VaadinUiUtil; import de.symeda.sormas.ui.utils.components.automaticdeletion.DeletionLabel; @@ -897,7 +895,7 @@ public CommitDiscardWrapperComponent getEventDataEditComponent(fi } else { VaadinUiUtil.showSimplePopupWindow( I18nProperties.getString(Strings.headingEventNotDeleted), - I18nProperties.getString(Strings.messageEventsNotDeletedReason)); + I18nProperties.getString(Strings.messageEventsNotDeletedLinkedEntitiesReason)); } UI.getCurrent().getNavigator().navigateTo(EventsView.VIEW_NAME); }, getDeleteConfirmationDetails(Collections.singletonList(eventUuid)), (deleteDetails) -> { @@ -970,14 +968,16 @@ public void showBulkEventDataEditComponent(Collection selectedEve List selectedEventsCpy = new ArrayList<>(selectedEvents); BulkOperationHandler. forBulkEdit() .doBulkOperation( - selectedEntries -> eventFacade.saveBulkEvents( - selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList()), - updatedTempEvent, - eventStatusChange, - eventInvestigationStatusChange, - eventManagementStatusChange), - selectedEventsCpy, - bulkOperationCallback(eventGrid, popupWindow)); + selectedEntries -> eventFacade.saveBulkEvents( + selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList()), + updatedTempEvent, + eventStatusChange, + eventInvestigationStatusChange, + eventManagementStatusChange), + selectedEventsCpy, + null, + null, + bulkOperationCallback(eventGrid, popupWindow)); }); editView.addDiscardListener(popupWindow::close); @@ -1006,95 +1006,33 @@ public EventDto createNewEvent(Disease disease) { return EventDto.build(FacadeProvider.getCountryFacade().getServerCountry(), UserProvider.getCurrent().getUser(), disease); } - public void deleteAllSelectedItems(Collection selectedRows, Runnable callback) { + public void deleteAllSelectedItems(Collection selectedRows, EventGrid eventGrid) { - if (selectedRows.size() == 0) { - new Notification( - I18nProperties.getString(Strings.headingNoEventsSelected), - I18nProperties.getString(Strings.messageNoEventsSelected), - Type.WARNING_MESSAGE, - false).show(Page.getCurrent()); - } else { - DeletableUtils.showDeleteWithReasonPopup( - String.format( - I18nProperties.getString(Strings.confirmationDeleteEvents), - selectedRows.size(), - getDeleteConfirmationDetails(selectedRows.stream().map(EventIndexDto::getUuid).collect(Collectors.toList()))), - (deleteDetails) -> { - StringBuilder nonDeletableEventsWithParticipants = new StringBuilder(); - int countNotDeletedEventsWithParticipants = 0; - StringBuilder nonDeletableEventsFromExternalTool = new StringBuilder(); - int countNotDeletedEventsFromExternalTool = 0; - for (EventIndexDto selectedRow : selectedRows) { - EventDto eventDto = FacadeProvider.getEventFacade().getEventByUuid(selectedRow.getUuid(), false); - if (existEventParticipantsLinkedToEvent(eventDto)) { - countNotDeletedEventsWithParticipants = countNotDeletedEventsWithParticipants + 1; - nonDeletableEventsWithParticipants.append(selectedRow.getUuid(), 0, 6).append(", "); - } else { - try { - FacadeProvider.getEventFacade().delete(eventDto.getUuid(), deleteDetails); - } catch (ExternalSurveillanceToolRuntimeException e) { - countNotDeletedEventsFromExternalTool = countNotDeletedEventsFromExternalTool + 1; - nonDeletableEventsFromExternalTool.append(selectedRow.getUuid(), 0, 6).append(", "); - } - } - } - if (nonDeletableEventsWithParticipants.length() > 0) { - nonDeletableEventsWithParticipants = new StringBuilder( - " " + nonDeletableEventsWithParticipants.substring(0, nonDeletableEventsWithParticipants.length() - 2) + ". "); - } - if (nonDeletableEventsFromExternalTool.length() > 0) { - nonDeletableEventsFromExternalTool = new StringBuilder( - " " + nonDeletableEventsFromExternalTool.substring(0, nonDeletableEventsFromExternalTool.length() - 2) + ". "); - } - callback.run(); - if (countNotDeletedEventsWithParticipants == 0 && countNotDeletedEventsFromExternalTool == 0) { - new Notification( - I18nProperties.getString(Strings.headingEventsDeleted), - I18nProperties.getString(Strings.messageEventsDeleted), - Type.HUMANIZED_MESSAGE, - false).show(Page.getCurrent()); - } else { - StringBuilder description = new StringBuilder(); - if (countNotDeletedEventsWithParticipants > 0) { - description.append( - String.format( - "%1s
%2s", - String.format( - I18nProperties.getString(Strings.messageCountEventsNotDeleted), - String.format("%s", countNotDeletedEventsWithParticipants), - String.format("%s", HtmlHelper.cleanHtml(nonDeletableEventsWithParticipants.toString()))), - I18nProperties.getString(Strings.messageEventsNotDeletedReason))) - .append("

"); - } - if (countNotDeletedEventsFromExternalTool > 0) { - description.append( - String.format( - "%1s
%2s", - String.format( - I18nProperties.getString(Strings.messageCountEventsNotDeletedExternalSurveillanceTool), - String.format("%s", countNotDeletedEventsFromExternalTool), - String.format("%s", HtmlHelper.cleanHtml(nonDeletableEventsFromExternalTool.toString()))), - I18nProperties.getString(Strings.messageEventsNotDeletedReasonExternalSurveillanceTool))); - } - - Window response = VaadinUiUtil.showSimplePopupWindow( - I18nProperties.getString(Strings.headingSomeEventsNotDeleted), - description.toString(), - ContentMode.HTML); - response.setWidth(600, Sizeable.Unit.PIXELS); - } - }); - } + Collection ineligibleEvents = new ArrayList<>(); + selectedRows.stream().forEach(row -> { + List eventParticipantList = + FacadeProvider.getEventParticipantFacade().getAllActiveEventParticipantsByEvent(row.getUuid()); + if (eventParticipantList.size() > 0) { + ineligibleEvents.add(row); + } + }); + + Collection eligibleEvents = ineligibleEvents.size() > 0 + ? selectedRows.stream().filter(row -> !ineligibleEvents.contains(row)).collect(Collectors.toCollection(ArrayList::new)) + : selectedRows; + + ControllerProvider.getDeleteRestoreController() + .deleteAllSelectedItems( + selectedRows, + eligibleEvents, + ineligibleEvents, + DeleteRestoreHandlers.forEvent(), + bulkOperationCallback(eventGrid, null)); } - public void restoreSelectedEvents(Collection selectedRows, Runnable callback) { + public void restoreSelectedEvents(Collection selectedRows, EventGrid eventGrid) { ControllerProvider.getDeleteRestoreController() - .restoreSelectedItems( - selectedRows.stream().map(EventIndexDto::getUuid).collect(Collectors.toList()), - FacadeProvider.getEventFacade(), - CoreEntityRestoreMessages.EVENT, - callback); + .restoreSelectedItems(selectedRows, DeleteRestoreHandlers.forEvent(), bulkOperationCallback(eventGrid, null)); } private Boolean existEventParticipantsLinkedToEvent(EventDto event) { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventParticipantsController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventParticipantsController.java index ce0af0cf2f3..c4ee3f11bc6 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventParticipantsController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventParticipantsController.java @@ -18,9 +18,10 @@ package de.symeda.sormas.ui.events; import java.util.Collection; +import java.util.List; import java.util.function.Consumer; -import java.util.stream.Collectors; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import com.vaadin.navigator.Navigator; @@ -55,9 +56,9 @@ import de.symeda.sormas.ui.UserProvider; import de.symeda.sormas.ui.utils.ArchiveHandlers; import de.symeda.sormas.ui.utils.CommitDiscardWrapperComponent; -import de.symeda.sormas.ui.utils.CoreEntityRestoreMessages; import de.symeda.sormas.ui.utils.DateFormatHelper; import de.symeda.sormas.ui.utils.DeletableUtils; +import de.symeda.sormas.ui.utils.DeleteRestoreHandlers; import de.symeda.sormas.ui.utils.VaadinUiUtil; import de.symeda.sormas.ui.utils.components.automaticdeletion.DeletionLabel; import de.symeda.sormas.ui.utils.components.page.title.TitleLayout; @@ -173,37 +174,31 @@ public void navigateToData(String eventParticipantUuid) { SormasUI.get().getNavigator().navigateTo(navigationState); } - public void deleteAllSelectedItems(Collection selectedRows, Runnable callback) { - if (selectedRows.size() == 0) { - new Notification( - I18nProperties.getString(Strings.headingNoEventParticipantsSelected), - I18nProperties.getString(Strings.messageNoEventParticipantsSelected), - Type.WARNING_MESSAGE, - false).show(Page.getCurrent()); - } else { - DeletableUtils.showDeleteWithReasonPopup( - String.format(I18nProperties.getString(Strings.confirmationDeleteEventParticipants), selectedRows.size()), - (deleteDetails) -> { - for (Object selectedRow : selectedRows) { - FacadeProvider.getEventParticipantFacade().delete(((EventParticipantIndexDto) selectedRow).getUuid(), deleteDetails); - } - callback.run(); - new Notification( - I18nProperties.getString(Strings.headingEventParticipantsDeleted), - I18nProperties.getString(Strings.messageEventParticipantsDeleted), - Type.HUMANIZED_MESSAGE, - false).show(Page.getCurrent()); - }); - } + public void deleteAllSelectedItems( + Collection selectedRows, + EventParticipantsGrid eventParticipantGrid, + Runnable noEntriesRemainingCallback) { + + ControllerProvider.getDeleteRestoreController() + .deleteAllSelectedItems( + selectedRows, + null, + null, + DeleteRestoreHandlers.forEventParticipant(), + bulkOperationCallback(eventParticipantGrid, noEntriesRemainingCallback, null)); + } - public void restoreSelectedEventParticipants(Collection selectedRows, Runnable callback) { + public void restoreSelectedEventParticipants( + Collection selectedRows, + EventParticipantsGrid eventParticipantGrid, + Runnable noEntriesRemainingCallback) { + ControllerProvider.getDeleteRestoreController() .restoreSelectedItems( - selectedRows.stream().map(EventParticipantIndexDto::getUuid).collect(Collectors.toList()), - FacadeProvider.getEventParticipantFacade(), - CoreEntityRestoreMessages.EVENT_PARTICIPANT, - callback); + selectedRows, + DeleteRestoreHandlers.forEventParticipant(), + bulkOperationCallback(eventParticipantGrid, noEntriesRemainingCallback, null)); } public void deleteEventParticipant(String eventUuid, String personUuid, Runnable callback) { @@ -376,4 +371,22 @@ public TitleLayout getEventParticipantViewTitleLayout(EventParticipantDto eventP return titleLayout; } + + private Consumer> bulkOperationCallback( + EventParticipantsGrid eventParticipantsGrid, + Runnable noEntriesRemainingCallback, + Window popupWindow) { + return remainingEventParticipants -> { + if (popupWindow != null) { + popupWindow.close(); + } + + eventParticipantsGrid.reload(); + if (CollectionUtils.isNotEmpty(remainingEventParticipants)) { + eventParticipantsGrid.asMultiSelect().selectItems(remainingEventParticipants.toArray(new EventParticipantIndexDto[0])); + } else { + noEntriesRemainingCallback.run(); + } + }; + } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventParticipantsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventParticipantsView.java index 4296180311e..b1561f9cd06 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventParticipantsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventParticipantsView.java @@ -223,13 +223,13 @@ public HorizontalLayout createTopBar() { if (criteria.getRelevanceStatus() != EntityRelevanceStatus.DELETED) { bulkActions.add(new MenuBarHelper.MenuBarItem(I18nProperties.getCaption(Captions.bulkDelete), VaadinIcons.TRASH, mi -> { grid.bulkActionHandler(items -> { - ControllerProvider.getEventParticipantController().deleteAllSelectedItems(items, () -> grid.reload()); + ControllerProvider.getEventParticipantController().deleteAllSelectedItems(items, grid, () -> grid.reload()); }, true); })); } else { bulkActions.add(new MenuBarHelper.MenuBarItem(I18nProperties.getCaption(Captions.bulkRestore), VaadinIcons.ARROW_BACKWARD, mi -> { grid.bulkActionHandler(items -> { - ControllerProvider.getEventParticipantController().restoreSelectedEventParticipants(items, () -> grid.reload()); + ControllerProvider.getEventParticipantController().restoreSelectedEventParticipants(items, grid, () -> grid.reload()); }, true); })); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventsView.java index 201a64f6249..6a35dd949f1 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventsView.java @@ -550,7 +550,7 @@ public HorizontalLayout createStatusFilterBar() { I18nProperties.getCaption(Captions.bulkDelete), VaadinIcons.TRASH, mi -> grid.bulkActionHandler( - items -> ControllerProvider.getEventController().deleteAllSelectedItems(items, () -> navigateTo(eventCriteria)), + items -> ControllerProvider.getEventController().deleteAllSelectedItems(items, (EventGrid) grid), true))); } else { bulkActions.add( @@ -558,7 +558,7 @@ public HorizontalLayout createStatusFilterBar() { I18nProperties.getCaption(Captions.bulkRestore), VaadinIcons.ARROW_BACKWARD, mi -> grid.bulkActionHandler( - items -> ControllerProvider.getEventController().restoreSelectedEvents(items, () -> navigateTo(eventCriteria)), + items -> ControllerProvider.getEventController().restoreSelectedEvents(items, (EventGrid) grid), true))); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageController.java index d7f8e9aa03b..5fa5fb9c997 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageController.java @@ -21,10 +21,12 @@ import java.util.Map; import java.util.Optional; import java.util.function.BiFunction; +import java.util.function.Consumer; import java.util.stream.Collectors; import javax.naming.NamingException; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -79,6 +81,7 @@ import de.symeda.sormas.ui.externalmessage.processing.flow.ProcessingResultStatus; import de.symeda.sormas.ui.utils.ButtonHelper; import de.symeda.sormas.ui.utils.CssStyles; +import de.symeda.sormas.ui.utils.DeleteRestoreHandlers; import de.symeda.sormas.ui.utils.VaadinUiUtil; public class ExternalMessageController { @@ -274,34 +277,22 @@ public void assignAllSelectedItems(Collection selectedR } } - public void deleteAllSelectedItems(Collection selectedRows, Runnable callback) { + public void deleteAllSelectedItems( + Collection selectedRows, + ExternalMessageGrid externalMessageGrid, + Runnable noEntriesRemainingCallback) { + + ControllerProvider.getPermanentDeleteController() + .deleteAllSelectedItems( + selectedRows, + DeleteRestoreHandlers.forExternalMessage(), + isEligibleForDeletion(selectedRows), + bulkOperationCallback(externalMessageGrid, noEntriesRemainingCallback, null)); - if (selectedRows.isEmpty()) { - new Notification( - I18nProperties.getString(Strings.headingNoExternalMessagesSelected), - I18nProperties.getString(Strings.messageNoExternalMessagesSelected), - Notification.Type.WARNING_MESSAGE, - false).show(Page.getCurrent()); - } else if (selectedRows.stream().anyMatch(m -> m.getStatus() == ExternalMessageStatus.PROCESSED)) { - new Notification( - I18nProperties.getString(Strings.headingExternalMessagesDeleteProcessed), - I18nProperties.getString(Strings.messageExternalMessagesDeleteProcessed), - Notification.Type.ERROR_MESSAGE, - false).show(Page.getCurrent()); - } else { - VaadinUiUtil.showDeleteConfirmationWindow( - String.format(I18nProperties.getString(Strings.confirmationDeleteExternalMessages), selectedRows.size()), - () -> { - FacadeProvider.getExternalMessageFacade() - .deleteExternalMessages(selectedRows.stream().map(ExternalMessageIndexDto::getUuid).collect(Collectors.toList())); - callback.run(); - new Notification( - I18nProperties.getString(Strings.headingExternalMessagesDeleted), - I18nProperties.getString(Strings.messageExternalMessagesDeleted), - Notification.Type.HUMANIZED_MESSAGE, - false).show(Page.getCurrent()); - }); - } + } + + public boolean isEligibleForDeletion(Collection selectedRows) { + return !selectedRows.stream().anyMatch(m -> m.getStatus() == ExternalMessageStatus.PROCESSED); } private HorizontalLayout getExternalMessageButtonsPanel(ExternalMessageDto externalMessage, Runnable callback) { @@ -319,7 +310,7 @@ private HorizontalLayout getExternalMessageButtonsPanel(ExternalMessageDto exter if (FacadeProvider.getExternalMessageFacade().isProcessed(externalMessage.getUuid())) { showAlreadyProcessedPopup(null, false); } else { - FacadeProvider.getExternalMessageFacade().deleteExternalMessage(externalMessage.getUuid()); + FacadeProvider.getExternalMessageFacade().delete(externalMessage.getUuid()); callback.run(); } }), @@ -482,4 +473,22 @@ private void saveAssignee(ExternalMessageDto externalMessageDto, UserReferenceDt public void registerViews(Navigator navigator) { navigator.addView(ExternalMessagesView.VIEW_NAME, ExternalMessagesView.class); } + + private Consumer> bulkOperationCallback( + ExternalMessageGrid externalMessageGrid, + Runnable noEntriesRemainingCallback, + Window popupWindow) { + return remainingExternalMessages -> { + if (popupWindow != null) { + popupWindow.close(); + } + + externalMessageGrid.reload(); + if (CollectionUtils.isNotEmpty(remainingExternalMessages)) { + externalMessageGrid.asMultiSelect().selectItems(remainingExternalMessages.toArray(new ExternalMessageIndexDto[0])); + } else { + noEntriesRemainingCallback.run(); + } + }; + } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessagesView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessagesView.java index 931b73ec56e..a1892ed036b 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessagesView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessagesView.java @@ -183,7 +183,7 @@ private MenuBar createBulkOperationsDropdown() { if (UserProvider.getCurrent().hasUserRight(UserRight.EXTERNAL_MESSAGE_DELETE)) { menuBarItems.add(new MenuBarHelper.MenuBarItem(I18nProperties.getCaption(Captions.bulkDelete), VaadinIcons.TRASH, mi -> { ControllerProvider.getExternalMessageController() - .deleteAllSelectedItems(grid.asMultiSelect().getSelectedItems(), () -> navigateTo(criteria)); + .deleteAllSelectedItems(grid.asMultiSelect().getSelectedItems(), grid, () -> navigateTo(criteria)); }, true)); } menuBarItems.add( diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleController.java index 522d56beaf1..96a16d89aa1 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleController.java @@ -23,12 +23,11 @@ import java.util.Collection; import java.util.List; import java.util.function.Consumer; -import java.util.stream.Collectors; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import com.vaadin.navigator.Navigator; -import com.vaadin.server.Page; import com.vaadin.server.Sizeable.Unit; import com.vaadin.shared.ui.ContentMode; import com.vaadin.ui.Alignment; @@ -82,12 +81,11 @@ import de.symeda.sormas.ui.utils.ButtonHelper; import de.symeda.sormas.ui.utils.CommitDiscardWrapperComponent; import de.symeda.sormas.ui.utils.ConfirmationComponent; -import de.symeda.sormas.ui.utils.CoreEntityRestoreMessages; import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.DateComparisonValidator; import de.symeda.sormas.ui.utils.DateFormatHelper; import de.symeda.sormas.ui.utils.DateTimeField; -import de.symeda.sormas.ui.utils.DeletableUtils; +import de.symeda.sormas.ui.utils.DeleteRestoreHandlers; import de.symeda.sormas.ui.utils.NullableOptionGroup; import de.symeda.sormas.ui.utils.VaadinUiUtil; import de.symeda.sormas.ui.utils.components.page.title.TitleLayout; @@ -617,37 +615,25 @@ public void buttonClick(ClickEvent event) { }); } - public void deleteAllSelectedItems(Collection selectedRows, Runnable callback) { + public void deleteAllSelectedItems(Collection selectedRows, SampleGrid sampleGrid, Runnable noEntriesRemainingCallback) { + + ControllerProvider.getDeleteRestoreController() + .deleteAllSelectedItems( + selectedRows, + null, + null, + DeleteRestoreHandlers.forSample(), + bulkOperationCallback(sampleGrid, noEntriesRemainingCallback, null)); - if (selectedRows.size() == 0) { - new Notification( - I18nProperties.getString(Strings.headingNoSamplesSelected), - I18nProperties.getString(Strings.messageNoSamplesSelected), - Type.WARNING_MESSAGE, - false).show(Page.getCurrent()); - } else { - DeletableUtils.showDeleteWithReasonPopup( - String.format(I18nProperties.getString(Strings.confirmationDeleteSamples), selectedRows.size()), - (deletionDetails) -> { - List sampleIndexDtoList = selectedRows.stream().map(SampleIndexDto::getUuid).collect(Collectors.toList()); - FacadeProvider.getSampleFacade().deleteAllSamples(sampleIndexDtoList, deletionDetails); - callback.run(); - new Notification( - I18nProperties.getString(Strings.headingSamplesDeleted), - I18nProperties.getString(Strings.messageSamplesDeleted), - Type.HUMANIZED_MESSAGE, - false).show(Page.getCurrent()); - }); - } } - public void restoreSelectedSamples(Collection selectedRows, Runnable callback) { + public void restoreSelectedSamples(Collection selectedRows, SampleGrid sampleGrid, Runnable noEntriesRemainingCallback) { + ControllerProvider.getDeleteRestoreController() .restoreSelectedItems( - selectedRows.stream().map(SampleIndexDto::getUuid).collect(Collectors.toList()), - FacadeProvider.getSampleFacade(), - CoreEntityRestoreMessages.SAMPLE, - callback); + selectedRows, + DeleteRestoreHandlers.forSample(), + bulkOperationCallback(sampleGrid, noEntriesRemainingCallback, null)); } public TitleLayout getSampleViewTitleLayout(SampleDto sample) { @@ -696,4 +682,19 @@ public Disease getDiseaseOf(SampleDto sample) { } return null; } + + private Consumer> bulkOperationCallback(SampleGrid sampleGrid, Runnable noEntriesRemainingCallback, Window popupWindow) { + return remainingSamples -> { + if (popupWindow != null) { + popupWindow.close(); + } + + sampleGrid.reload(); + if (CollectionUtils.isNotEmpty(remainingSamples)) { + sampleGrid.asMultiSelect().selectItems(remainingSamples.toArray(new SampleIndexDto[0])); + } else { + noEntriesRemainingCallback.run(); + } + }; + } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleGridComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleGridComponent.java index 085524eab67..30cab037805 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleGridComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleGridComponent.java @@ -188,23 +188,15 @@ public HorizontalLayout createShipmentFilterBar() { bulkOperationsDropdown = MenuBarHelper.createDropDown( Captions.bulkActions, new MenuBarHelper.MenuBarItem(I18nProperties.getCaption(Captions.bulkDelete), VaadinIcons.TRASH, selectedItem -> { - ControllerProvider.getSampleController().deleteAllSelectedItems(grid.asMultiSelect().getSelectedItems(), new Runnable() { - - public void run() { - samplesView.navigateTo(criteria); - } - }); + ControllerProvider.getSampleController() + .deleteAllSelectedItems(grid.asMultiSelect().getSelectedItems(), grid, () -> samplesView.navigateTo(criteria)); })); } else { bulkOperationsDropdown = MenuBarHelper.createDropDown( Captions.bulkActions, new MenuBarHelper.MenuBarItem(I18nProperties.getCaption(Captions.bulkRestore), VaadinIcons.ARROW_BACKWARD, selectedItem -> { - ControllerProvider.getSampleController().restoreSelectedSamples(grid.asMultiSelect().getSelectedItems(), new Runnable() { - - public void run() { - samplesView.navigateTo(criteria); - } - }); + ControllerProvider.getSampleController() + .restoreSelectedSamples(grid.asMultiSelect().getSelectedItems(), grid, () -> samplesView.navigateTo(criteria)); })); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskController.java index a1b55cf928f..afe757a21bb 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskController.java @@ -51,6 +51,7 @@ import de.symeda.sormas.ui.utils.ArchivingController; import de.symeda.sormas.ui.utils.BulkOperationHandler; import de.symeda.sormas.ui.utils.CommitDiscardWrapperComponent; +import de.symeda.sormas.ui.utils.DeleteRestoreHandlers; import de.symeda.sormas.ui.utils.VaadinUiUtil; public class TaskController { @@ -142,7 +143,7 @@ public void edit(TaskIndexDto taskIndex, Runnable callback, boolean editedFromTa if (UserProvider.getCurrent().hasUserRight(UserRight.TASK_DELETE)) { editView.addDeleteListener(() -> { - FacadeProvider.getTaskFacade().deleteTask(task); + FacadeProvider.getTaskFacade().delete(task.getUuid()); UI.getCurrent().removeWindow(popupWindow); callback.run(); }, I18nProperties.getString(Strings.entityTask)); @@ -169,28 +170,15 @@ private TaskDto createNewTask(TaskContext context, ReferenceDto entityRef) { return task; } - public void deleteAllSelectedItems(Collection selectedRows, Runnable callback) { + public void deleteAllSelectedItems(Collection selectedRows, TaskGrid taskGrid, Runnable noEntriesRemainingCallback) { + + ControllerProvider.getPermanentDeleteController() + .deleteAllSelectedItems( + selectedRows, + DeleteRestoreHandlers.forTask(), + true, + bulkOperationCallback(taskGrid, noEntriesRemainingCallback, null)); - if (selectedRows.size() == 0) { - new Notification( - I18nProperties.getString(Strings.headingNoTasksSelected), - I18nProperties.getString(Strings.messageNoTasksSelected), - Type.WARNING_MESSAGE, - false).show(Page.getCurrent()); - } else { - VaadinUiUtil - .showDeleteConfirmationWindow(String.format(I18nProperties.getString(Strings.confirmationDeleteTasks), selectedRows.size()), () -> { - for (TaskIndexDto selectedRow : selectedRows) { - FacadeProvider.getTaskFacade().deleteTask(FacadeProvider.getTaskFacade().getByUuid(selectedRow.getUuid())); - } - callback.run(); - new Notification( - I18nProperties.getString(Strings.headingTasksDeleted), - I18nProperties.getString(Strings.messageTasksDeleted), - Type.HUMANIZED_MESSAGE, - false).show(Page.getCurrent()); - }); - } } public void showBulkTaskDataEditComponent(Collection selectedTasks, TaskGrid taskGrid, Runnable noEntriesRemainingCallback) { @@ -219,14 +207,16 @@ public void showBulkTaskDataEditComponent(Collection selectedTasks List selectedTasksCpy = new ArrayList<>(selectedTasks); BulkOperationHandler. forBulkEdit() .doBulkOperation( - selectedEntries -> taskFacade.saveBulkTasks( - selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList()), - updatedTempTask, - form.getPriorityCheckbox().getValue(), - form.getAssigneeCheckbox().getValue(), - form.getTaskStatusCheckbox().getValue()), - selectedTasksCpy, - bulkOperationCallback(taskGrid, noEntriesRemainingCallback, popupWindow)); + selectedEntries -> taskFacade.saveBulkTasks( + selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList()), + updatedTempTask, + form.getPriorityCheckbox().getValue(), + form.getAssigneeCheckbox().getValue(), + form.getTaskStatusCheckbox().getValue()), + selectedTasksCpy, + null, + null, + bulkOperationCallback(taskGrid, noEntriesRemainingCallback, popupWindow)); }); editView.addDiscardListener(popupWindow::close); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskGridComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskGridComponent.java index 21655380a9c..2897504da12 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskGridComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskGridComponent.java @@ -186,7 +186,7 @@ public HorizontalLayout createAssigneeFilterBar() { I18nProperties.getCaption(Captions.bulkDelete), VaadinIcons.TRASH, selectedItem -> ControllerProvider.getTaskController() - .deleteAllSelectedItems(this.grid.asMultiSelect().getSelectedItems(), () -> tasksView.navigateTo(criteria)), + .deleteAllSelectedItems(this.grid.asMultiSelect().getSelectedItems(), grid, () -> tasksView.navigateTo(criteria)), hasBulkOperationsRight)); menuBarItems.add( new MenuBarHelper.MenuBarItem( diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntriesView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntriesView.java index 03bfa8098b5..6e2483642da 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntriesView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntriesView.java @@ -248,7 +248,8 @@ public HorizontalLayout createStatusFilterBar() { I18nProperties.getCaption(Captions.bulkDelete), VaadinIcons.TRASH, mi -> grid.bulkActionHandler( - items -> ControllerProvider.getTravelEntryController().deleteAllSelectedItems(items, () -> navigateTo(criteria)), + items -> ControllerProvider.getTravelEntryController() + .deleteAllSelectedItems(items, (TravelEntryGrid) grid, () -> navigateTo(criteria)), true))); } else { bulkActions.add( @@ -256,7 +257,8 @@ public HorizontalLayout createStatusFilterBar() { I18nProperties.getCaption(Captions.bulkRestore), VaadinIcons.ARROW_BACKWARD, mi -> grid.bulkActionHandler( - items -> ControllerProvider.getTravelEntryController().restoreSelectedTravelEntries(items, () -> navigateTo(criteria)), + items -> ControllerProvider.getTravelEntryController() + .restoreSelectedTravelEntries(items, (TravelEntryGrid) grid, () -> navigateTo(criteria)), true))); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryController.java index 4f6e2251dc2..21e6b3aa364 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryController.java @@ -1,13 +1,15 @@ package de.symeda.sormas.ui.travelentry; import java.util.Collection; -import java.util.stream.Collectors; +import java.util.List; +import java.util.function.Consumer; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import com.vaadin.navigator.Navigator; -import com.vaadin.server.Page; import com.vaadin.ui.Notification; +import com.vaadin.ui.Window; import de.symeda.sormas.api.FacadeProvider; import de.symeda.sormas.api.caze.CaseDataDto; @@ -29,8 +31,7 @@ import de.symeda.sormas.ui.travelentry.components.TravelEntryCreateForm; import de.symeda.sormas.ui.utils.ArchiveHandlers; import de.symeda.sormas.ui.utils.CommitDiscardWrapperComponent; -import de.symeda.sormas.ui.utils.CoreEntityRestoreMessages; -import de.symeda.sormas.ui.utils.DeletableUtils; +import de.symeda.sormas.ui.utils.DeleteRestoreHandlers; import de.symeda.sormas.ui.utils.VaadinUiUtil; import de.symeda.sormas.ui.utils.components.automaticdeletion.DeletionLabel; import de.symeda.sormas.ui.utils.components.page.title.TitleLayout; @@ -172,11 +173,7 @@ public CommitDiscardWrapperComponent getTravelEntryDataEdit // Initialize 'Archive' button if (UserProvider.getCurrent().hasUserRight(UserRight.TRAVEL_ENTRY_ARCHIVE)) { ControllerProvider.getArchiveController() - .addArchivingButton( - travelEntry, - ArchiveHandlers.forTravelEntry(), - editComponent, - () -> navigateToTravelEntry(travelEntry.getUuid())); + .addArchivingButton(travelEntry, ArchiveHandlers.forTravelEntry(), editComponent, () -> navigateToTravelEntry(travelEntry.getUuid())); } editComponent.restrictEditableComponentsOnEditView( @@ -214,37 +211,48 @@ public TitleLayout getTravelEntryViewTitleLayout(String uuid) { return titleLayout; } - public void deleteAllSelectedItems(Collection selectedRows, Runnable callback) { - if (selectedRows.size() == 0) { - new Notification( - I18nProperties.getString(Strings.headingNoTravelEntriesSelected), - I18nProperties.getString(Strings.messageNoTravelEntriesSelected), - Notification.Type.WARNING_MESSAGE, - false).show(Page.getCurrent()); - } else { - DeletableUtils.showDeleteWithReasonPopup( - String.format(I18nProperties.getString(Strings.confirmationDeleteTravelEntries), selectedRows.size()), - (deleteDetails) -> { - for (TravelEntryIndexDto selectedRow : selectedRows) { - FacadeProvider.getTravelEntryFacade().delete(selectedRow.getUuid(), deleteDetails); - } - callback.run(); - new Notification( - I18nProperties.getString(Strings.headingTravelEntriesDeleted), - I18nProperties.getString(Strings.messageTravelEntriesDeleted), - Notification.Type.HUMANIZED_MESSAGE, - false).show(Page.getCurrent()); - }); - } + public void deleteAllSelectedItems( + Collection selectedRows, + TravelEntryGrid travelEntryGrid, + Runnable noEntriesRemainingCallback) { + + ControllerProvider.getDeleteRestoreController() + .deleteAllSelectedItems( + selectedRows, + null, + null, + DeleteRestoreHandlers.forTravelEntry(), + bulkOperationCallback(travelEntryGrid, noEntriesRemainingCallback, null)); + } - public void restoreSelectedTravelEntries(Collection selectedRows, Runnable callback) { + public void restoreSelectedTravelEntries( + Collection selectedRows, + TravelEntryGrid travelEntryGrid, + Runnable noEntriesRemainingCallback) { ControllerProvider.getDeleteRestoreController() .restoreSelectedItems( - selectedRows.stream().map(TravelEntryIndexDto::getUuid).collect(Collectors.toList()), - FacadeProvider.getTravelEntryFacade(), - CoreEntityRestoreMessages.TRAVEL_ENTRY, - callback); + selectedRows, + DeleteRestoreHandlers.forTravelEntry(), + bulkOperationCallback(travelEntryGrid, noEntriesRemainingCallback, null)); + } + + private Consumer> bulkOperationCallback( + TravelEntryGrid travelEntryGrid, + Runnable noEntriesRemainingCallback, + Window popupWindow) { + return remainingTravelEntries -> { + if (popupWindow != null) { + popupWindow.close(); + } + + travelEntryGrid.reload(); + if (CollectionUtils.isNotEmpty(remainingTravelEntries)) { + travelEntryGrid.asMultiSelect().selectItems(remainingTravelEntries.toArray(new TravelEntryIndexDto[0])); + } else { + noEntriesRemainingCallback.run(); + } + }; } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/ArchivingController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/ArchivingController.java index b79b775d5ef..6b39fbff2de 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/ArchivingController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/ArchivingController.java @@ -205,6 +205,8 @@ this. createBulkOperationHandler(archiveHandler, true) selectedEntries -> archiveHandler .archive(selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList())), selectedCasesCpy, + null, + null, batchCallback); } }); @@ -215,7 +217,12 @@ private BulkOperationHandler createBulkOperationHandler(I ArchiveMessages archiveMessages = archiveHandler.getArchiveMessages(); return new BulkOperationHandler<>( forArchive ? archiveMessages.getMessageAllEntitiesArchived() : archiveMessages.getMessageAllEntitiesDearchived(), - forArchive ? archiveMessages.getMessageSomeEntitiesArchived() : archiveMessages.getMessageSomeEntitiesDearchived()); + null, + null, + null, + forArchive ? archiveMessages.getMessageSomeEntitiesArchived() : archiveMessages.getMessageSomeEntitiesDearchived(), + null, + Strings.infoBulkProcessFinishedWithSkips); } public void dearchiveSelectedItems( @@ -259,6 +266,8 @@ this. createBulkOperationHandler(archiveHandler, false) selectedEntries -> archiveHandler .dearchive(selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList())), selectedCasesCpy, + null, + null, batchCallback); } return true; diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/BulkOperationHandler.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/BulkOperationHandler.java index b4d8ba3ef43..180af732240 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/BulkOperationHandler.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/BulkOperationHandler.java @@ -6,8 +6,10 @@ import java.util.concurrent.locks.ReentrantLock; import java.util.function.Consumer; import java.util.function.Function; +import java.util.stream.Collectors; import com.vaadin.server.Sizeable; +import com.vaadin.shared.ui.ContentMode; import com.vaadin.ui.Label; import com.vaadin.ui.Notification; import com.vaadin.ui.UI; @@ -18,6 +20,7 @@ import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.i18n.Strings; import de.symeda.sormas.api.user.UserDto; +import de.symeda.sormas.api.utils.HtmlHelper; import de.symeda.sormas.api.uuid.HasUuid; import de.symeda.sormas.ui.utils.components.progress.BulkProgressLayout; import de.symeda.sormas.ui.utils.components.progress.BulkProgressUpdateInfo; @@ -38,36 +41,92 @@ public class BulkOperationHandler { private boolean cancelButtonClicked; private final Lock cancelLock = new ReentrantLock(); private int initialEntryCount; + private int initialEligibleEntryCount; private int successfulEntryCount; + private Window window; private final String allEntriesProcessedMessageProperty; + private final String ineligibleEntriesNotProcessedMessageProperty; + private final String headingSomeEntitiesNotProcessed; + private final String countEntriesNotProcessedMessageProperty; private final String someEntriesProcessedMessageProperty; + private final String noEligibleEntityMessageProperty; + private final String infoBulkProcessFinishedWithSkipsProperty; - public BulkOperationHandler(String allEntriesProcessedMessageProperty, String someEntriesProcessedMessageProperty) { + public BulkOperationHandler( + String allEntriesProcessedMessageProperty, + String ineligibleEntriesNotProcessedMessageProperty, + String headingSomeEntitiesNotProcessed, + String countEntriesNotProcessedMessageProperty, + String someEntriesProcessedMessageProperty, + String noEligibleEntityMessageProperty, + String infoBulkProcessFinishedWithSkipsProperty) { this.allEntriesProcessedMessageProperty = allEntriesProcessedMessageProperty; + this.ineligibleEntriesNotProcessedMessageProperty = ineligibleEntriesNotProcessedMessageProperty; + this.headingSomeEntitiesNotProcessed = headingSomeEntitiesNotProcessed; + this.countEntriesNotProcessedMessageProperty = countEntriesNotProcessedMessageProperty; this.someEntriesProcessedMessageProperty = someEntriesProcessedMessageProperty; + this.noEligibleEntityMessageProperty = noEligibleEntityMessageProperty; + this.infoBulkProcessFinishedWithSkipsProperty = infoBulkProcessFinishedWithSkipsProperty; } public static BulkOperationHandler forBulkEdit() { - return new BulkOperationHandler(Strings.messageEntriesEdited, Strings.messageEntriesEditedExceptArchived); + return new BulkOperationHandler( + Strings.messageEntriesEdited, + null, + null, + null, + Strings.messageEntriesEditedExceptArchived, + null, + Strings.infoBulkProcessFinishedWithSkips); } public void doBulkOperation( Function, Integer> bulkOperationFunction, List selectedEntries, + List selectedEligibleEntries, + List selectedIneligibleEntries, Consumer> bulkOperationDoneCallback) { initialEntryCount = selectedEntries.size(); + initialEligibleEntryCount = getInitialEligibleEntryCount(selectedEntries, selectedIneligibleEntries, selectedEligibleEntries); + selectedEligibleEntries = !areIneligibleEntriesSelected(selectedIneligibleEntries) ? selectedEntries : selectedEligibleEntries; + if (selectedEntries.size() < BULK_ACTION_PROGRESS_THRESHOLD) { - successfulEntryCount = bulkOperationFunction.apply(selectedEntries); - if (initialEntryCount > successfulEntryCount) { + if (initialEligibleEntryCount > 0) { + successfulEntryCount = areIneligibleEntriesSelected(selectedIneligibleEntries) + ? bulkOperationFunction.apply(selectedEligibleEntries) + : bulkOperationFunction.apply(selectedEntries); + } + + if (initialEligibleEntryCount == 0 && successfulEntryCount == 0) { + //all the selected items were ineligible + NotificationHelper.showNotification(I18nProperties.getString(noEligibleEntityMessageProperty), Notification.Type.WARNING_MESSAGE, -1); + return; + } + + if (initialEligibleEntryCount > successfulEntryCount) { NotificationHelper.showNotification( String.format(I18nProperties.getString(someEntriesProcessedMessageProperty), successfulEntryCount), Notification.Type.HUMANIZED_MESSAGE, -1); + } else { - NotificationHelper - .showNotification(I18nProperties.getString(allEntriesProcessedMessageProperty), Notification.Type.HUMANIZED_MESSAGE, -1); + if (areIneligibleEntriesSelected(selectedIneligibleEntries)) { + String description = getErrorDescription( + selectedIneligibleEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList()), + I18nProperties.getString(countEntriesNotProcessedMessageProperty), + I18nProperties.getString(ineligibleEntriesNotProcessedMessageProperty)); + + Window response = + VaadinUiUtil.showSimplePopupWindow(I18nProperties.getString(headingSomeEntitiesNotProcessed), description, ContentMode.HTML); + + response.setWidth(600, Sizeable.Unit.PIXELS); + } else { + //all the selected eligible entities were processed + NotificationHelper + .showNotification(I18nProperties.getString(allEntriesProcessedMessageProperty), Notification.Type.HUMANIZED_MESSAGE, -1); + } } bulkOperationDoneCallback.accept(Collections.emptyList()); } else { @@ -75,41 +134,62 @@ public void doBulkOperation( UI currentUI = UI.getCurrent(); BulkProgressLayout bulkProgressLayout = new BulkProgressLayout(currentUI, selectedEntries.size(), this::handleCancelButtonClicked); - Window window = VaadinUiUtil.createPopupWindow(); - window.setCaption(I18nProperties.getString(Strings.headingBulkOperationProgress)); - window.setWidth(800, Sizeable.Unit.PIXELS); - window.setContent(bulkProgressLayout); - window.setClosable(false); - currentUI.addWindow(window); + addWindow(bulkProgressLayout, currentUI); + List finalSelectedEligibleEntries = selectedEligibleEntries; Thread bulkThread = new Thread(() -> { currentUI.setPollInterval(300); I18nProperties.setUserLanguage(currentUser.getLanguage()); FacadeProvider.getI18nFacade().setUserLanguage(currentUser.getLanguage()); try { - List remainingEntries = performBulkOperation(bulkOperationFunction, selectedEntries, bulkProgressLayout::updateProgress); + List remainingEntries = + performBulkOperation(bulkOperationFunction, finalSelectedEligibleEntries, bulkProgressLayout::updateProgress); currentUI.access(() -> { window.setClosable(true); - if (cancelAfterCurrentBatch) { + + if (initialEligibleEntryCount == 0) { bulkProgressLayout.finishProgress( ProgressResult.SUCCESS_WITH_WARNING, - I18nProperties.getString(Strings.infoBulkProcessCancelled), + I18nProperties.getString(Strings.infoBulkProcessNoEligibleEntries), () -> { window.close(); bulkOperationDoneCallback.accept(remainingEntries); }); - } else if (initialEntryCount == successfulEntryCount) { - bulkProgressLayout - .finishProgress(ProgressResult.SUCCESS, I18nProperties.getString(Strings.infoBulkProcessFinished), () -> { + return; + } + + if (cancelAfterCurrentBatch) { + bulkProgressLayout.finishProgress( + ProgressResult.SUCCESS_WITH_WARNING, + I18nProperties.getString(Strings.infoBulkProcessCancelled), + () -> { window.close(); bulkOperationDoneCallback.accept(remainingEntries); }); + } else if (initialEligibleEntryCount == successfulEntryCount) { + + if (initialEntryCount == initialEligibleEntryCount) { + bulkProgressLayout + .finishProgress(ProgressResult.SUCCESS, I18nProperties.getString(Strings.infoBulkProcessFinished), () -> { + window.close(); + bulkOperationDoneCallback.accept(remainingEntries); + }); + } else { + + bulkProgressLayout.finishProgress( + ProgressResult.SUCCESS_WITH_WARNING, + I18nProperties.getString(Strings.infoBulkProcessFinishedWithIneligibleItems), + () -> { + window.close(); + bulkOperationDoneCallback.accept(remainingEntries); + }); + } } else { bulkProgressLayout.finishProgress( ProgressResult.SUCCESS_WITH_WARNING, - I18nProperties.getString(Strings.infoBulkProcessFinishedWithSkips), + I18nProperties.getString(infoBulkProcessFinishedWithSkipsProperty), () -> { window.close(); bulkOperationDoneCallback.accept(remainingEntries); @@ -182,4 +262,55 @@ private void handleCancelButtonClicked() { } + private String getErrorDescription( + List ineligibleEntityUuids, + String messageCountEntriesNotProcessed, + String messageIneligibleEntriesNotProcessed) { + StringBuilder description = new StringBuilder(); + description.append( + String.format( + "%1s
%2s", + String.format( + messageCountEntriesNotProcessed, + String.format("%s", ineligibleEntityUuids.size()), + String.format("%s", HtmlHelper.cleanHtml(getIneligibleItemsString(ineligibleEntityUuids)))), + messageIneligibleEntriesNotProcessed)) + .append("

"); + + return description.toString(); + } + + public String getIneligibleItemsString(List ineligibleEntities) { + StringBuilder ineligibleItems = new StringBuilder(); + for (String ineligibleEntity : ineligibleEntities) { + ineligibleItems.append(ineligibleEntity, 0, 6).append(", "); + } + + if (ineligibleItems.length() > 0) { + ineligibleItems = new StringBuilder(" " + ineligibleItems.substring(0, ineligibleItems.length() - 2) + ". "); + } + + return ineligibleItems.toString(); + } + + public int getInitialEligibleEntryCount(List selectedEntries, List selectedIneligibleEntries, List selectedEligibleEntries) { + return selectedIneligibleEntries != null && selectedIneligibleEntries.size() > 0 ? selectedEligibleEntries.size() : selectedEntries.size(); + } + + public boolean areIneligibleEntriesSelected(List selectedIneligibleEntries) { + return selectedIneligibleEntries != null && selectedIneligibleEntries.size() > 0; + } + + public Window getWindow() { + return window; + } + + public void addWindow(BulkProgressLayout layout, UI currentUI) { + window = VaadinUiUtil.createPopupWindow(); + window.setCaption(I18nProperties.getString(Strings.headingBulkOperationProgress)); + window.setWidth(800, Sizeable.Unit.PIXELS); + window.setContent(layout); + window.setClosable(false); + currentUI.addWindow(window); + } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CoreEntityRestoreMessages.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CoreEntityRestoreMessages.java deleted file mode 100644 index 3bfcac5cdef..00000000000 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CoreEntityRestoreMessages.java +++ /dev/null @@ -1,115 +0,0 @@ -package de.symeda.sormas.ui.utils; - -import de.symeda.sormas.api.i18n.Strings; - -public enum CoreEntityRestoreMessages { - - CASE(Strings.entityCases, - Strings.headingNoCasesSelected, - Strings.messageNoCasesSelected, - Strings.headingCasesRestored, - Strings.messageCasesRestored, - Strings.headingSomeCasesNotRestored, - Strings.messageCountCasesNotRestored), - - CONTACT(Strings.entityContacts, - Strings.headingNoContactsSelected, - Strings.messageNoContactsSelected, - Strings.headingContactsRestored, - Strings.messageContactsRestored, - Strings.headingSomeContactsNotRestored, - Strings.messageCountContactsNotRestored), - - EVENT(Strings.entityEvents, - Strings.headingNoEventsSelected, - Strings.messageNoEventsSelected, - Strings.headingEventsRestored, - Strings.messageEventsRestored, - Strings.headingSomeEventsNotRestored, - Strings.messageCountEventsNotRestored), - - EVENT_PARTICIPANT(Strings.entityEventParticipants, - Strings.headingNoEventParticipantsSelected, - Strings.messageNoEventParticipantsSelected, - Strings.headingEventParticipantsRestored, - Strings.messageEventParticipantsRestored, - Strings.headingSomeEventParticipantsNotRestored, - Strings.messageCountEventParticipantsNotRestored), - - IMMUNIZATION(Strings.entityImmunizations, - Strings.headingNoImmunizationsSelected, - Strings.messageNoImmunizationsSelected, - Strings.headingImmunizationsRestored, - Strings.messageImmunizationsRestored, - Strings.headingSomeImmunizationsNotRestored, - Strings.messageCountImmunizationsNotRestored), - - SAMPLE(Strings.entitySamples, - Strings.headingNoSamplesSelected, - Strings.messageNoSamplesSelected, - Strings.headingSamplesRestored, - Strings.messageSamplesRestored, - Strings.headingSomeSamplesNotRestored, - Strings.messageCountSamplesNotRestored), - - TRAVEL_ENTRY(Strings.entityTravelEntries, - Strings.headingNoTravelEntriesSelected, - Strings.messageNoTravelEntriesSelected, - Strings.headingTravelEntriesRestored, - Strings.messageTravelEntriesRestored, - Strings.headingSomeTravelEntriesNotRestored, - Strings.messageCountTravelEntriesNotRestored); - - private final String entities; - private final String headingNoSelection; - private final String messageNoSelection; - private final String headingEntitiesRestored; - private final String messageEntitiesRestored; - private final String headingSomeEntitiesNotRestored; - private final String messageCountEntitiesNotRestored; - - CoreEntityRestoreMessages( - String entities, - String headingNoSelection, - String messageNoSelection, - String headingEntitiesRestored, - String messageEntitiesRestored, - String headingSomeEntitiesNotRestored, - String messageCountEntitiesNotRestored) { - this.entities = entities; - this.headingNoSelection = headingNoSelection; - this.messageNoSelection = messageNoSelection; - this.headingEntitiesRestored = headingEntitiesRestored; - this.messageEntitiesRestored = messageEntitiesRestored; - this.headingSomeEntitiesNotRestored = headingSomeEntitiesNotRestored; - this.messageCountEntitiesNotRestored = messageCountEntitiesNotRestored; - } - - public String getEntities() { - return entities; - } - - public String getHeadingNoSelection() { - return headingNoSelection; - } - - public String getMessageNoSelection() { - return messageNoSelection; - } - - public String getHeadingEntitiesRestored() { - return headingEntitiesRestored; - } - - public String getMessageEntitiesRestored() { - return messageEntitiesRestored; - } - - public String getHeadingSomeEntitiesNotRestored() { - return headingSomeEntitiesNotRestored; - } - - public String getMessageCountEntitiesNotRestored() { - return messageCountEntitiesNotRestored; - } -} diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/DeleteRestoreController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/DeleteRestoreController.java index 21ce843b699..7035d5efba2 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/DeleteRestoreController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/DeleteRestoreController.java @@ -1,29 +1,36 @@ package de.symeda.sormas.ui.utils; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Collectors; import com.vaadin.server.Page; -import com.vaadin.server.Sizeable; import com.vaadin.shared.ui.ContentMode; +import com.vaadin.ui.ComboBox; import com.vaadin.ui.Label; import com.vaadin.ui.Notification; -import com.vaadin.ui.Window; +import com.vaadin.ui.TextArea; +import com.vaadin.ui.VerticalLayout; import de.symeda.sormas.api.DeletableFacade; +import de.symeda.sormas.api.FacadeProvider; +import de.symeda.sormas.api.common.DeletionDetails; +import de.symeda.sormas.api.common.DeletionReason; import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.i18n.Strings; -import de.symeda.sormas.api.utils.HtmlHelper; +import de.symeda.sormas.api.uuid.HasUuid; public class DeleteRestoreController { - public void restoreSelectedItems(List entityUuids, F entityFacade, CoreEntityRestoreMessages messages, Runnable callback) { + public void restoreSelectedItems( + Collection entities, + IDeleteRestoreHandler deleteHandler, + Consumer> batchCallback) { - if (entityUuids.isEmpty()) { - new Notification( - I18nProperties.getString(messages.getHeadingNoSelection()), - I18nProperties.getString(messages.getMessageNoSelection()), - Notification.Type.WARNING_MESSAGE, - false).show(Page.getCurrent()); + if (entities.isEmpty()) { + displayNothingSelectedToBeRestored(deleteHandler.getDeleteRestoreMessages()); return; } @@ -31,8 +38,8 @@ public void restoreSelectedItems(List entityUuids, F entityFacade, CoreE restoreConfirmationMessage.setValue( String.format( I18nProperties.getString(Strings.confirmationRestoreEntities), - entityUuids.size(), - I18nProperties.getString(messages.getEntities()))); + entities.size(), + I18nProperties.getString(deleteHandler.getDeleteRestoreMessages().getEntities()).toLowerCase())); VaadinUiUtil.showConfirmationPopup( I18nProperties.getString(Strings.headingRestoreConfirmation), @@ -42,54 +49,149 @@ public void restoreSelectedItems(List entityUuids, F entityFacade, CoreE 500, confirmed -> { if (Boolean.TRUE.equals(confirmed)) { - performRestoreSelectedItems(entityUuids, entityFacade, messages, callback); + List selectedEntitiesCpy = new ArrayList<>(entities); + List selectedEligibleEntitiesCpy = new ArrayList<>(entities); + this. createBulkOperationHandler(deleteHandler, false) + .doBulkOperation( + selectedEntries -> deleteHandler.restore(selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList())), + selectedEntitiesCpy, + selectedEligibleEntitiesCpy, + null, + batchCallback); } }); } - private void performRestoreSelectedItems(List entityUuids, F entityFacade, CoreEntityRestoreMessages messages, Runnable callback) { + public void deleteAllSelectedItems( + Collection entities, + Collection eligibleEntities, + Collection ineligibleEntities, + IDeleteRestoreHandler deleteHandler, + Consumer> batchCallback) { - int unrestoredEntityCount = 0; - StringBuilder unrestoredEntitiesSb = new StringBuilder(); - - for (String selectedRow : entityUuids) { - try { - entityFacade.restore(selectedRow); - } catch (Exception e) { - unrestoredEntityCount++; - unrestoredEntitiesSb.append(selectedRow, 0, 6).append(", "); - } + if (entities.isEmpty()) { + displayNothingSelectedToBeDeleted(deleteHandler.getDeleteRestoreMessages()); + return; } - if (unrestoredEntitiesSb.length() > 0) { - unrestoredEntitiesSb = new StringBuilder(" " + unrestoredEntitiesSb.substring(0, unrestoredEntitiesSb.length() - 2) + ". "); - } + String deleteWithReasonConfirmationMessage = String.format( + I18nProperties.getString(Strings.confirmationDeleteEntities), + entities.size(), + I18nProperties.getString(deleteHandler.getDeleteRestoreMessages().getEntities()).toLowerCase()) + + getDeleteConfirmationDetails(deleteHandler.getDeleteRestoreMessages().getEntities(), entities); + + VerticalLayout verticalLayout = new VerticalLayout(); + verticalLayout.setMargin(false); + + Label contentLabel = new Label(deleteWithReasonConfirmationMessage, ContentMode.HTML); + contentLabel.addStyleName(CssStyles.LABEL_WHITE_SPACE_NORMAL); + contentLabel.setWidthFull(); + verticalLayout.addComponent(contentLabel); + + deleteHandler.addAdditionalDeleteReasonField(verticalLayout); + + VaadinUiUtil.showConfirmationPopup( + I18nProperties.getString(Strings.headingDeleteConfirmation), + verticalLayout, + I18nProperties.getString(Strings.yes), + I18nProperties.getString(Strings.no), + 640, + confirmed -> { + if (Boolean.TRUE.equals(confirmed)) { + if (!deleteHandler.validateAdditionalDeleteReasonFields()) { + return false; + } + deleteHandler.clearOtherReason(); + + List selectedEntitiesCpy = new ArrayList<>(entities); + List selectedEligibleEntitiesCpy = eligibleEntities != null ? new ArrayList<>(eligibleEntities) : new ArrayList<>(entities); + List selectedIneligibleEntitiesCpy = ineligibleEntities != null ? new ArrayList<>(ineligibleEntities) : null; + this. createBulkOperationHandler(deleteHandler, true) + .doBulkOperation( + selectedEntries -> deleteHandler.delete( + selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList()), + new DeletionDetails( + deleteHandler.getDeleteReasonComboBox().getValue(), + deleteHandler.getOtherDeletionReason().getValue())), + selectedEntitiesCpy, + selectedEligibleEntitiesCpy, + selectedIneligibleEntitiesCpy, + batchCallback); + } + + return true; + }); + } - callback.run(); - handleRestoreResult(unrestoredEntityCount, messages, unrestoredEntitiesSb.toString()); + private BulkOperationHandler createBulkOperationHandler(IDeleteRestoreHandler deleteHandler, boolean forDelete) { + DeleteRestoreMessages deleteRestoreMessages = deleteHandler.getDeleteRestoreMessages(); + return new BulkOperationHandler<>( + + forDelete ? deleteRestoreMessages.getMessageEntitiesDeleted() : deleteRestoreMessages.getMessageEntitiesRestored(), + forDelete ? deleteRestoreMessages.getMessageEntitiesNotDeletedLinkedEntitiesReason() : null, + forDelete ? deleteRestoreMessages.getHeadingSomeEntitiesNotDeleted() : deleteRestoreMessages.getHeadingSomeEntitiesNotRestored(), + forDelete ? deleteRestoreMessages.getMessageCountEntitiesNotDeleted() : deleteRestoreMessages.getMessageCountEntitiesNotRestored(), + forDelete ? deleteRestoreMessages.getMessageEntitiesNotDeleted() : deleteRestoreMessages.getMessageEntitiesNotRestored(), + forDelete ? deleteRestoreMessages.getMessageNoEligibleEntitySelected() : null, + Strings.infoBulkProcessFinishedWithSkipsOutsideJurisdiction); } - private void handleRestoreResult(int unrestoredEntityCount, CoreEntityRestoreMessages messages, String unrestoredEntitiesString) { - - if (unrestoredEntityCount == 0) { - new Notification( - I18nProperties.getString(messages.getHeadingEntitiesRestored()), - I18nProperties.getString(messages.getMessageEntitiesRestored()), - Notification.Type.TRAY_NOTIFICATION, - false).show(Page.getCurrent()); - } else { - Window response = VaadinUiUtil.showSimplePopupWindow( - I18nProperties.getString(messages.getHeadingSomeEntitiesNotRestored()), - String.format( - "%1s

%2s", - String.format( - I18nProperties.getString(messages.getMessageCountEntitiesNotRestored()), - String.format("%s", unrestoredEntityCount), - String.format("%s", HtmlHelper.cleanHtml(unrestoredEntitiesString))), - I18nProperties.getString(Strings.messageCasesNotRestored)), - ContentMode.HTML); - response.setWidth(600, Sizeable.Unit.PIXELS); + private void displayNothingSelectedToBeDeleted(DeleteRestoreMessages messages) { + new Notification( + I18nProperties.getString(messages.getHeadingNoSelection()), + I18nProperties.getString(messages.getMessageNoSelection()), + Notification.Type.WARNING_MESSAGE, + false).show(Page.getCurrent()); + } + + private void displayNothingSelectedToBeRestored(DeleteRestoreMessages messages) { + new Notification( + I18nProperties.getString(messages.getHeadingNoSelection()), + I18nProperties.getString(messages.getMessageNoSelection()), + Notification.Type.WARNING_MESSAGE, + false).show(Page.getCurrent()); + } + + public String getDeleteConfirmationDetails(String entity, Collection entities) { + + List entitiesList = entities.stream().map(T::getUuid).collect(Collectors.toList()); + boolean hasPendingRequest = false; + switch (entity) { + case "entityCases": + hasPendingRequest = FacadeProvider.getSormasToSormasCaseFacade().hasPendingRequest(entitiesList); + break; + case "entityContacts": + hasPendingRequest = FacadeProvider.getSormasToSormasContactFacade().hasPendingRequest(entitiesList); + break; + case "entityEvents": + hasPendingRequest = FacadeProvider.getSormasToSormasEventFacade().hasPendingRequest(entitiesList); + break; + default: + break; } + return hasPendingRequest ? "

" + I18nProperties.getString(Strings.messageDeleteWithPendingShareRequest) + "
" : ""; + } + + public interface IDeleteRestoreHandler { + + void delete(String uuid, DeletionDetails deletionDetails); + + int delete(List uuids, DeletionDetails deletionDetails); + + int restore(List uuids); + + DeleteRestoreMessages getDeleteRestoreMessages(); + + void addAdditionalDeleteReasonField(VerticalLayout verticalLayout); + + boolean validateAdditionalDeleteReasonFields(); + + ComboBox getDeleteReasonComboBox(); + + TextArea getOtherDeletionReason(); + + void clearOtherReason(); + } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/DeleteRestoreHandlers.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/DeleteRestoreHandlers.java new file mode 100644 index 00000000000..67f0de0563c --- /dev/null +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/DeleteRestoreHandlers.java @@ -0,0 +1,211 @@ +package de.symeda.sormas.ui.utils; + +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; + +import com.vaadin.server.Sizeable; +import com.vaadin.server.UserError; +import com.vaadin.ui.ComboBox; +import com.vaadin.ui.TextArea; +import com.vaadin.ui.VerticalLayout; + +import de.symeda.sormas.api.CoreFacade; +import de.symeda.sormas.api.DeletableFacade; +import de.symeda.sormas.api.EntityDto; +import de.symeda.sormas.api.FacadeProvider; +import de.symeda.sormas.api.PermanentlyDeletableFacade; +import de.symeda.sormas.api.common.DeletionDetails; +import de.symeda.sormas.api.common.DeletionReason; +import de.symeda.sormas.api.i18n.Captions; +import de.symeda.sormas.api.i18n.I18nProperties; +import de.symeda.sormas.api.i18n.Strings; +import de.symeda.sormas.api.sample.SampleDto; +import de.symeda.sormas.api.sample.SampleFacade; +import de.symeda.sormas.api.utils.FieldConstraints; + +public final class DeleteRestoreHandlers { + + private DeleteRestoreHandlers() { + + } + + public static CoreEntityDeleteRestoreHandler forCase() { + return new CoreEntityDeleteRestoreHandler<>(FacadeProvider.getCaseFacade(), DeleteRestoreMessages.CASE); + } + + public static CoreEntityDeleteRestoreHandler forContact() { + return new CoreEntityDeleteRestoreHandler<>(FacadeProvider.getContactFacade(), DeleteRestoreMessages.CONTACT); + } + + public static CoreEntityDeleteRestoreHandler forEvent() { + return new CoreEntityDeleteRestoreHandler<>(FacadeProvider.getEventFacade(), DeleteRestoreMessages.EVENT); + } + + public static CoreEntityDeleteRestoreHandler forEventParticipant() { + return new CoreEntityDeleteRestoreHandler<>(FacadeProvider.getEventParticipantFacade(), DeleteRestoreMessages.EVENT_PARTICIPANT); + } + + public static CoreEntityDeleteRestoreHandler forTravelEntry() { + return new CoreEntityDeleteRestoreHandler<>(FacadeProvider.getTravelEntryFacade(), DeleteRestoreMessages.TRAVEL_ENTRY); + } + + public static SampleDeleteRestoreHandler forSample() { + return new SampleDeleteRestoreHandler(); + } + + public static PermanentDeleteHandler forTask() { + return new PermanentDeleteHandler(FacadeProvider.getTaskFacade(), DeleteRestoreMessages.TASK); + } + + public static PermanentDeleteHandler forVisit() { + return new PermanentDeleteHandler(FacadeProvider.getVisitFacade(), DeleteRestoreMessages.VISIT); + } + + public static PermanentDeleteHandler forExternalMessage() { + return new PermanentDeleteHandler(FacadeProvider.getExternalMessageFacade(), DeleteRestoreMessages.EXTERNAL_MESSAGE); + } + + public static class DeleteRestoreHandler + implements DeleteRestoreController.IDeleteRestoreHandler { + + protected final F entityFacade; + private final DeleteRestoreMessages deleteRestoreMessages; + + protected ComboBox deleteReasonComboBox; + protected TextArea otherDeletionReason; + + private DeleteRestoreHandler(F entityFacade, DeleteRestoreMessages deleteRestoreMessages) { + this.entityFacade = entityFacade; + this.deleteRestoreMessages = deleteRestoreMessages; + } + + @Override + public void delete(String uuid, DeletionDetails deletionDetails) { + } + + @Override + public int delete(List uuids, DeletionDetails deletionDetails) { + entityFacade.delete(uuids, deletionDetails); + return uuids.size(); + } + + @Override + public int restore(List uuids) { + entityFacade.restore(uuids); + return uuids.size(); + } + + @Override + public DeleteRestoreMessages getDeleteRestoreMessages() { + return deleteRestoreMessages; + } + + @Override + public void addAdditionalDeleteReasonField(VerticalLayout verticalLayout) { + deleteReasonComboBox = new ComboBox(null, Arrays.asList(DeletionReason.values())); + deleteReasonComboBox.setCaption(I18nProperties.getCaption(Captions.deletionReason)); + deleteReasonComboBox.setWidth(100, Sizeable.Unit.PERCENTAGE); + deleteReasonComboBox.setRequiredIndicatorVisible(true); + verticalLayout.addComponent(deleteReasonComboBox); + + otherDeletionReason = new TextArea(); + otherDeletionReason.setCaption(I18nProperties.getCaption(Captions.otherDeletionReason)); + verticalLayout.addComponent(otherDeletionReason); + otherDeletionReason.setVisible(false); + otherDeletionReason.setWidth(100, Sizeable.Unit.PERCENTAGE); + otherDeletionReason.setRows(3); + otherDeletionReason.setMaxLength(FieldConstraints.CHARACTER_LIMIT_TEXT); + otherDeletionReason.setRequiredIndicatorVisible(true); + + deleteReasonComboBox.addValueChangeListener(valueChangeEvent -> { + otherDeletionReason.setVisible(valueChangeEvent.getValue() == (DeletionReason.OTHER_REASON)); + }); + + deleteReasonComboBox.addValueChangeListener(valueChangeEvent -> { + if (deleteReasonComboBox.isEmpty()) { + deleteReasonComboBox.setComponentError(new UserError(I18nProperties.getString(Strings.messageDeleteReasonNotFilled))); + } else { + deleteReasonComboBox.setComponentError(null); + } + }); + + otherDeletionReason.addValueChangeListener(valueChangeEvent -> { + if (deleteReasonComboBox.getValue() == DeletionReason.OTHER_REASON && StringUtils.isBlank(otherDeletionReason.getValue())) { + otherDeletionReason.setComponentError(new UserError(I18nProperties.getString(Strings.messageOtherDeleteReasonNotFilled))); + } else { + otherDeletionReason.setComponentError(null); + } + }); + } + + @Override + public boolean validateAdditionalDeleteReasonFields() { + if (deleteReasonComboBox.isEmpty()) { + deleteReasonComboBox.setComponentError(new UserError(I18nProperties.getString(Strings.messageDeleteReasonNotFilled))); + return false; + } else if (deleteReasonComboBox.getValue() == DeletionReason.OTHER_REASON && StringUtils.isBlank(otherDeletionReason.getValue())) { + otherDeletionReason.setComponentError(new UserError(I18nProperties.getString(Strings.messageOtherDeleteReasonNotFilled))); + return false; + } + + return true; + } + + @Override + public ComboBox getDeleteReasonComboBox() { + return deleteReasonComboBox; + } + + @Override + public TextArea getOtherDeletionReason() { + return otherDeletionReason; + } + + @Override + public void clearOtherReason() { + if (deleteReasonComboBox.getValue() != DeletionReason.OTHER_REASON && !StringUtils.isBlank(otherDeletionReason.getValue())) { + otherDeletionReason.clear(); + } + } + } + + public static class CoreEntityDeleteRestoreHandler> extends DeleteRestoreHandler + implements DeleteRestoreController.IDeleteRestoreHandler { + + protected CoreEntityDeleteRestoreHandler(F entityFacade, DeleteRestoreMessages deleteRestoreMessages) { + super(entityFacade, deleteRestoreMessages); + } + } + + public static class SampleDeleteRestoreHandler extends DeleteRestoreHandler { + + protected SampleDeleteRestoreHandler() { + super(FacadeProvider.getSampleFacade(), DeleteRestoreMessages.SAMPLE); + } + } + + public static class PermanentDeleteHandler + implements PermanentDeleteController.IPermanentDeleteHandler { + + protected final F entityFacade; + private final DeleteRestoreMessages deleteRestoreMessages; + + private PermanentDeleteHandler(F entityFacade, DeleteRestoreMessages deleteRestoreMessages) { + this.entityFacade = entityFacade; + this.deleteRestoreMessages = deleteRestoreMessages; + } + + @Override + public int delete(List uuids) { + entityFacade.delete(uuids); + return uuids.size(); + } + + @Override + public DeleteRestoreMessages getDeleteRestoreMessages() { + return deleteRestoreMessages; + } + } +} diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/DeleteRestoreMessages.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/DeleteRestoreMessages.java new file mode 100644 index 00000000000..30745f21255 --- /dev/null +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/DeleteRestoreMessages.java @@ -0,0 +1,313 @@ +package de.symeda.sormas.ui.utils; + +import de.symeda.sormas.api.i18n.Strings; + +public enum DeleteRestoreMessages { + + CASE(Strings.entityCases, + Strings.headingNoCasesSelected, + Strings.messageNoCasesSelected, + null, + null, + Strings.headingCasesDeleted, + Strings.messageCasesDeleted, + Strings.messageCasesNotDeleted, + Strings.messageCasesNotDeletedExternalReason, + null, + Strings.headingSomeCasesNotDeleted, + Strings.messageCountCasesNotDeleted, + Strings.headingCasesRestored, + Strings.messageCasesRestored, + Strings.messageCasesNotRestored, + Strings.headingSomeCasesNotRestored, + Strings.messageCountCasesNotRestored), + + EVENT(Strings.entityEvents, + Strings.headingNoEventsSelected, + Strings.messageNoEventsSelected, + Strings.messageNoEligibleEventForDeletionSelected, + null, + Strings.headingEventsDeleted, + Strings.messageEventsDeleted, + Strings.messageEventsNotDeleted, + Strings.messageEventsNotDeletedExternalReason, + Strings.messageEventsNotDeletedLinkedEntitiesReason, + Strings.headingSomeEventsNotDeleted, + Strings.messageCountEventsNotDeleted, + Strings.headingEventsRestored, + Strings.messageEventsRestored, + Strings.messageEventsNotRestored, + Strings.headingSomeEventsNotRestored, + Strings.messageCountEventsNotRestored), + + EVENT_PARTICIPANT(Strings.entityEventParticipants, + Strings.headingNoEventParticipantsSelected, + Strings.messageNoEventParticipantsSelected, + null, + null, + Strings.headingEventParticipantsDeleted, + Strings.messageEventParticipantsDeleted, + Strings.messageEventParticipantsNotDeleted, + null, + null, + Strings.headingSomeEventParticipantsNotDeleted, + Strings.messageCountEventParticipantsNotDeleted, + Strings.headingEventParticipantsRestored, + Strings.messageEventParticipantsRestored, + Strings.messageEventParticipantsNotRestored, + Strings.headingSomeEventParticipantsNotRestored, + Strings.messageCountEventParticipantsNotRestored), + + CONTACT(Strings.entityContacts, + Strings.headingNoContactsSelected, + Strings.messageNoContactsSelected, + null, + null, + Strings.headingContactsDeleted, + Strings.messageContactsDeleted, + Strings.messageContactsNotDeleted, + null, + null, + Strings.headingSomeContactsNotDeleted, + Strings.messageCountContactsNotDeleted, + Strings.headingContactsRestored, + Strings.messageContactsRestored, + Strings.messageContactsNotRestored, + Strings.headingSomeContactsNotRestored, + Strings.messageCountContactsNotRestored), + + TRAVEL_ENTRY(Strings.entityTravelEntries, + Strings.headingNoTravelEntriesSelected, + Strings.messageNoTravelEntriesSelected, + null, + null, + Strings.headingTravelEntriesDeleted, + Strings.messageTravelEntriesDeleted, + Strings.messageTravelEntriesNotDeleted, + null, + null, + Strings.headingSomeTravelEntriesNotDeleted, + Strings.messageCountTravelEntriesNotDeleted, + Strings.headingTravelEntriesRestored, + Strings.messageTravelEntriesRestored, + Strings.messageTravelEntriesNotRestored, + Strings.headingSomeTravelEntriesNotRestored, + Strings.messageCountTravelEntriesNotRestored), + + VISIT(Strings.entityVisits, + Strings.headingNoVisitsSelected, + Strings.messageNoVisitsSelected, + null, + null, + Strings.headingVisitsDeleted, + Strings.messageVisitsDeleted, + Strings.messageVisitsNotDeleted, + null, + null, + Strings.headingSomeVisitsNotDeleted, + Strings.messageCountVisitsNotDeleted, + null, + null, + null, + null, + null), + + TASK(Strings.entityTasks, + Strings.headingNoTasksSelected, + Strings.messageNoTasksSelected, + null, + null, + Strings.headingTasksDeleted, + Strings.messageTasksDeleted, + Strings.messageTasksNotDeleted, + null, + null, + Strings.headingSomeTasksNotDeleted, + Strings.messageCountTasksNotDeleted, + null, + null, + null, + null, + null), + + EXTERNAL_MESSAGE(Strings.entityExternalMessages, + Strings.headingNoExternalMessagesSelected, + Strings.messageNoExternalMessagesSelected, + null, + Strings.messageExternalMessagesEligibleForDeletion, + Strings.headingExternalMessagesDeleted, + Strings.messageExternalMessagesDeleted, + Strings.messageExternalMessagesNotDeleted, + null, + null, + Strings.headingSomeExternalMessagesNotDeleted, + Strings.messageCountExternalMessagesNotDeleted, + null, + null, + null, + null, + null), + + SAMPLE(Strings.entitySamples, + Strings.headingNoSamplesSelected, + Strings.messageNoSamplesSelected, + null, + null, + Strings.headingSamplesDeleted, + Strings.messageSamplesDeleted, + Strings.messageSamplesNotDeleted, + null, + null, + Strings.headingSomeSamplesNotDeleted, + Strings.messageCountSamplesNotDeleted, + Strings.headingSamplesRestored, + Strings.messageSamplesRestored, + Strings.messageSamplesNotRestored, + Strings.headingSomeSamplesNotRestored, + Strings.messageCountSamplesNotRestored), + + IMMUNIZATION(Strings.entityImmunizations, + Strings.headingNoImmunizationsSelected, + Strings.messageNoImmunizationsSelected, + null, + null, + null, + null, + null, + null, + null, + null, + null, + Strings.headingImmunizationsRestored, + Strings.messageImmunizationsRestored, + Strings.messageImmunizationsNotRestored, + Strings.headingSomeImmunizationsNotRestored, + Strings.messageCountImmunizationsNotRestored); + + private final String entities; + private final String headingNoSelection; + private final String messageNoSelection; + private final String messageNoEligibleEntitySelected; + private final String messageEntitiesEligibleForDeletion; + private final String headingEntitiesDeleted; + private final String messageEntitiesDeleted; + private final String messageEntitiesNotDeleted; + private final String messageEntitiesNotDeletedExternalReason; + private final String messageEntitiesNotDeletedLinkedEntitiesReason; + private final String headingSomeEntitiesNotDeleted; + private final String messageCountEntitiesNotDeleted; + + private final String headingEntitiesRestored; + private final String messageEntitiesRestored; + private final String messageEntitiesNotRestored; + private final String headingSomeEntitiesNotRestored; + private final String messageCountEntitiesNotRestored; + + DeleteRestoreMessages( + String entities, + String headingNoSelection, + String messageNoSelection, + String messageNoEligibleEntitySelected, + String messageEntitiesEligibleForDeletion, + String headingEntitiesDeleted, + String messageEntitiesDeleted, + String messageEntitiesNotDeleted, + String messageEntitiesNotDeletedExternalReason, + String messageEntitiesNotDeletedLinkedEntitiesReason, + String headingSomeEntitiesNotDeleted, + String messageCountEntitiesNotDeleted, + String headingEntitiesRestored, + String messageEntitiesRestored, + String messageEntitiesNotRestored, + String headingSomeEntitiesNotRestored, + String messageCountEntitiesNotRestored) { + + this.entities = entities; + this.headingNoSelection = headingNoSelection; + this.messageNoSelection = messageNoSelection; + this.messageNoEligibleEntitySelected = messageNoEligibleEntitySelected; + this.messageEntitiesEligibleForDeletion = messageEntitiesEligibleForDeletion; + this.headingEntitiesDeleted = headingEntitiesDeleted; + this.messageEntitiesDeleted = messageEntitiesDeleted; + this.messageEntitiesNotDeleted = messageEntitiesNotDeleted; + this.messageEntitiesNotDeletedExternalReason = messageEntitiesNotDeletedExternalReason; + this.messageEntitiesNotDeletedLinkedEntitiesReason = messageEntitiesNotDeletedLinkedEntitiesReason; + + this.headingSomeEntitiesNotDeleted = headingSomeEntitiesNotDeleted; + this.messageCountEntitiesNotDeleted = messageCountEntitiesNotDeleted; + + this.headingEntitiesRestored = headingEntitiesRestored; + this.messageEntitiesRestored = messageEntitiesRestored; + this.messageEntitiesNotRestored = messageEntitiesNotRestored; + this.headingSomeEntitiesNotRestored = headingSomeEntitiesNotRestored; + this.messageCountEntitiesNotRestored = messageCountEntitiesNotRestored; + } + + public String getEntities() { + return entities; + } + + public String getHeadingNoSelection() { + return headingNoSelection; + } + + public String getMessageNoSelection() { + return messageNoSelection; + } + + public String getMessageNoEligibleEntitySelected() { + return messageNoEligibleEntitySelected; + } + + public String getMessageEntitiesEligibleForDeletion() { + return messageEntitiesEligibleForDeletion; + } + + public String getHeadingEntitiesDeleted() { + return headingEntitiesDeleted; + } + + public String getMessageEntitiesDeleted() { + return messageEntitiesDeleted; + } + + public String getMessageEntitiesNotDeleted() { + return messageEntitiesNotDeleted; + } + + public String getMessageEntitiesNotDeletedExternalReason() { + return messageEntitiesNotDeletedExternalReason; + } + + public String getMessageEntitiesNotDeletedLinkedEntitiesReason() { + return messageEntitiesNotDeletedLinkedEntitiesReason; + } + + public String getHeadingSomeEntitiesNotDeleted() { + return headingSomeEntitiesNotDeleted; + } + + public String getMessageCountEntitiesNotDeleted() { + return messageCountEntitiesNotDeleted; + } + + public String getHeadingEntitiesRestored() { + return headingEntitiesRestored; + } + + public String getMessageEntitiesRestored() { + return messageEntitiesRestored; + } + + public String getMessageEntitiesNotRestored() { + return messageEntitiesNotRestored; + } + + public String getHeadingSomeEntitiesNotRestored() { + return headingSomeEntitiesNotRestored; + } + + public String getMessageCountEntitiesNotRestored() { + return messageCountEntitiesNotRestored; + } +} diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/PermanentDeleteController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/PermanentDeleteController.java new file mode 100644 index 00000000000..57e909650c2 --- /dev/null +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/PermanentDeleteController.java @@ -0,0 +1,107 @@ +package de.symeda.sormas.ui.utils; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import com.vaadin.server.Page; +import com.vaadin.shared.ui.ContentMode; +import com.vaadin.ui.Label; +import com.vaadin.ui.Notification; +import com.vaadin.ui.VerticalLayout; + +import de.symeda.sormas.api.PermanentlyDeletableFacade; +import de.symeda.sormas.api.i18n.I18nProperties; +import de.symeda.sormas.api.i18n.Strings; +import de.symeda.sormas.api.uuid.HasUuid; + +public class PermanentDeleteController { + + public void deleteAllSelectedItems( + Collection entities, + IPermanentDeleteHandler deleteHandler, + boolean allItemsAreEligibleForDeletion, + Consumer> batchCallback) { + + if (entities.isEmpty()) { + displayNothingSelectedToBeDeleted(deleteHandler.getDeleteRestoreMessages()); + return; + } + + if (!allItemsAreEligibleForDeletion) { + displayErrorMessage(deleteHandler.getDeleteRestoreMessages()); + return; + } + + String deleteConfirmationMessage = String.format( + I18nProperties.getString(Strings.confirmationDeleteEntities), + entities.size(), + I18nProperties.getString(deleteHandler.getDeleteRestoreMessages().getEntities()).toLowerCase()); + + VerticalLayout verticalLayout = new VerticalLayout(); + verticalLayout.setMargin(false); + + Label contentLabel = new Label(deleteConfirmationMessage, ContentMode.HTML); + contentLabel.addStyleName(CssStyles.LABEL_WHITE_SPACE_NORMAL); + contentLabel.setWidthFull(); + verticalLayout.addComponent(contentLabel); + + VaadinUiUtil.showConfirmationPopup( + I18nProperties.getString(Strings.headingDeleteConfirmation), + verticalLayout, + I18nProperties.getString(Strings.yes), + I18nProperties.getString(Strings.no), + 640, + confirmed -> { + if (Boolean.TRUE.equals(confirmed)) { + + List selectedEntitiesCpy = new ArrayList<>(entities); + this. createBulkOperationHandler(deleteHandler) + .doBulkOperation( + selectedEntries -> deleteHandler.delete(selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList())), + selectedEntitiesCpy, + null, + null, + batchCallback); + } + + return true; + }); + + } + + private void displayNothingSelectedToBeDeleted(DeleteRestoreMessages messages) { + new Notification( + I18nProperties.getString(messages.getHeadingNoSelection()), + I18nProperties.getString(messages.getMessageNoSelection()), + Notification.Type.WARNING_MESSAGE, + false).show(Page.getCurrent()); + } + + private void displayErrorMessage(DeleteRestoreMessages messages) { + new Notification(I18nProperties.getString(messages.getMessageEntitiesEligibleForDeletion()), Notification.Type.ERROR_MESSAGE) + .show(Page.getCurrent()); + } + + private BulkOperationHandler createBulkOperationHandler(IPermanentDeleteHandler deleteHandler) { + DeleteRestoreMessages deleteRestoreMessages = deleteHandler.getDeleteRestoreMessages(); + return new BulkOperationHandler<>( + deleteRestoreMessages.getMessageEntitiesDeleted(), + null, + deleteRestoreMessages.getHeadingSomeEntitiesNotDeleted(), + deleteRestoreMessages.getMessageCountEntitiesNotDeleted(), + deleteRestoreMessages.getMessageEntitiesNotDeleted(), + null, + Strings.infoBulkProcessFinishedWithSkipsOutsideJurisdiction); + } + + public interface IPermanentDeleteHandler { + + int delete(List uuids); + + DeleteRestoreMessages getDeleteRestoreMessages(); + } + +} diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/visit/VisitController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/visit/VisitController.java index 0e5c2d89a8e..2076b79e593 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/visit/VisitController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/visit/VisitController.java @@ -19,12 +19,12 @@ import java.util.Collection; import java.util.Date; +import java.util.List; import java.util.function.Consumer; -import com.vaadin.server.Page; +import org.apache.commons.collections.CollectionUtils; + import com.vaadin.server.Sizeable.Unit; -import com.vaadin.ui.Notification; -import com.vaadin.ui.Notification.Type; import com.vaadin.ui.UI; import com.vaadin.ui.Window; @@ -47,8 +47,10 @@ import de.symeda.sormas.api.visit.VisitIndexDto; import de.symeda.sormas.api.visit.VisitLogic; import de.symeda.sormas.api.visit.VisitReferenceDto; +import de.symeda.sormas.ui.ControllerProvider; import de.symeda.sormas.ui.UserProvider; import de.symeda.sormas.ui.utils.CommitDiscardWrapperComponent; +import de.symeda.sormas.ui.utils.DeleteRestoreHandlers; import de.symeda.sormas.ui.utils.VaadinUiUtil; public class VisitController { @@ -138,7 +140,7 @@ private void editVisit( if (canDelete) { editView.addDeleteListener(() -> { - FacadeProvider.getVisitFacade().deleteVisit(visitRef.getUuid()); + FacadeProvider.getVisitFacade().delete(visitRef.getUuid()); UI.getCurrent().removeWindow(window); if (doneConsumer != null) { doneConsumer.accept(visitRef); @@ -227,26 +229,29 @@ private VisitDto createNewVisit(CaseReferenceDto caseRef) { return createNewVisit(caze.getPerson(), caze.getDisease()); } - public void deleteAllSelectedItems(Collection selectedRows, Runnable callback) { - if (selectedRows.size() == 0) { - new Notification( - I18nProperties.getString(Strings.headingNoVisitsSelected), - I18nProperties.getString(Strings.messageNoVisitsSelected), - Type.WARNING_MESSAGE, - false).show(Page.getCurrent()); - } else { - VaadinUiUtil - .showDeleteConfirmationWindow(String.format(I18nProperties.getString(Strings.confirmationDeleteVisits), selectedRows.size()), () -> { - for (Object selectedRow : selectedRows) { - FacadeProvider.getVisitFacade().deleteVisit(((VisitIndexDto) selectedRow).getUuid()); - } - callback.run(); - new Notification( - I18nProperties.getString(Strings.headingVisitsDeleted), - I18nProperties.getString(Strings.messageVisitsDeleted), - Type.HUMANIZED_MESSAGE, - false).show(Page.getCurrent()); - }); - } + public void deleteAllSelectedItems(Collection selectedRows, VisitGrid visitGrid, Runnable noEntriesRemainingCallback) { + + ControllerProvider.getPermanentDeleteController() + .deleteAllSelectedItems( + selectedRows, + DeleteRestoreHandlers.forVisit(), + true, + bulkOperationCallback(visitGrid, noEntriesRemainingCallback, null)); + + } + + private Consumer> bulkOperationCallback(VisitGrid visitGrid, Runnable noEntriesRemainingCallback, Window popupWindow) { + return remainingVisits -> { + if (popupWindow != null) { + popupWindow.close(); + } + + visitGrid.reload(); + if (CollectionUtils.isNotEmpty(remainingVisits)) { + visitGrid.asMultiSelect().selectItems(remainingVisits.toArray(new VisitIndexDto[0])); + } else { + noEntriesRemainingCallback.run(); + } + }; } } From 37e67440dbbe50630896d342aef28a5381a57a17 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Fri, 14 Jul 2023 11:19:38 +0200 Subject: [PATCH 070/174] qu-auto/SORQA-1029 Implement "Pre-existing disease in case when sending from SORMAS to Meldesoftware". New test scenario have been provded. --- .../resources/features/sanity/web/Survnet.feature | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature index 183ca44acd6..bdbfdbdf2ab 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature @@ -221,4 +221,17 @@ Feature: Survnet tests And I open SORMAS generated XML file for event single message And I check if event external UUID in SORMAS generated XML file is correct And I check if "created at date" in SORMAS generated XML file is correct - And I check if "change at date" in SORMAS generated XML file is correct \ No newline at end of file + And I check if "change at date" in SORMAS generated XML file is correct + + @tmsLink=SORQA-1029 + Scenario: Pre-existing disease in case when sending from SORMAS to Meldesoftware + Given I log in as a Survnet + When I click on the Cases button from navbar + And I click on the NEW CASE button + And I create a new case with mandatory data only for Survnet DE + Then I change all pre-existing conditions to "YES" on Edit Case page + And I navigate to case tab + And I click on Send to reporting tool button on Edit Case page + And I collect case external UUID from Edit Case page + Then I wait 50 seconds for system reaction + And I open SORMAS generated XML file for single case message \ No newline at end of file From 8d11dff6c38f603489c1037899152428d4800b71 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Mon, 17 Jul 2023 08:15:07 +0200 Subject: [PATCH 071/174] qu-auto/SORQA-1029 Implement "Pre-existing disease in case when sending from SORMAS to Meldesoftware". New steps have been provided. --- .../pages/application/cases/EditCasePage.java | 4 + .../web/application/cases/EditCaseSteps.java | 208 +++++++++++++++++- .../web/application/survnet/SurvNetSteps.java | 104 +++++++-- .../features/sanity/web/Survnet.feature | 21 +- 4 files changed, 319 insertions(+), 18 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/EditCasePage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/EditCasePage.java index af3b4e09b45..0f8f3a2edad 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/EditCasePage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/EditCasePage.java @@ -407,6 +407,10 @@ public static By getPreExistingConditionComboboxWithValue_DE(String id, String v id, value)); } + public static By getPreExistingConditionComboboxToSelectValue_DE(String disease) { + return By.cssSelector(String.format("#%s [class='v-checkbox v-select-option']", disease)); + } + public static By getEditTaskButtonByNumber(Integer number) { return By.cssSelector(String.format("#edit%x", number)); } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java index 75622c8458d..705662ee2a0 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java @@ -46,7 +46,203 @@ import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CONTACTS_DATA_TAB; import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.EPIDEMIOLOGICAL_DATA_TAB; import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.DATE_OF_REPORT_NO_POPUP_INPUT; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.*; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.ACTION_CANCEL; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.ACTION_CONFIRM; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.ADD_A_PARTICIPANT_HEADER_DE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.ARCHIVE_CASE_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.ARCHIVE_RELATED_CONTACTS_CHECKBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.BACK_TO_CASES_LIST_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.BLOOD_ORGAN_TISSUE_DONATION_IN_THE_LAST_6_MONTHS_OPTIONS; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.BUTTONS_IN_VACCINATIONS_LOCATION; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.CANCEL_FOLLOW_UP_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.CASE_CLASSIFICATION_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.CASE_CLASSIFICATION_RADIOBUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.CASE_CLASSIFICATION_SPAN; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.CASE_CONFIRMATION_BASIS_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.CASE_IDENTIFICATION_SOURCE_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.CASE_ORIGIN; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.CASE_PERSON_TAB; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.CASE_SAVED_POPUP; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.CASE_TAB; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.CHANGE_DISEASE_CONFIRMATION_POPUP; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.CLINICAL_CONFIRMATION_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.CLINICAL_COURSE_TAB; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.COMMUNITY_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.COMMUNITY_COMBOBOX_BY_PLACE_OF_STAY; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.COMMUNITY_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.CONFIRM_ACTION; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.CREATE_DOCUMENT_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.CREATE_DOCUMENT_BUTTON_DE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.CREATE_DOCUMENT_TEMPLATES; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.CREATE_DOCUMENT_TEMPLATES_POPUP_DE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.CREATE_QUARANTINE_ORDER_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.CREATE_QUARANTINE_ORDER_BUTTON_DE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.CURRENT_HOSPITALIZATION_POPUP; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.DATE_OFFICIAL_QUARANTINE_ORDER_WAS_SENT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.DATE_OF_FOLLOW_UP_STATUS_CHANGE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.DATE_OF_FOLLOW_UP_STATUS_CHANGE_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.DATE_OF_OUTCOME; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.DATE_OF_OUTCOME_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.DATE_OF_THE_VERBAL_ORDER; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.DATE_RECEIVED_AT_DISTRICT_LEVEL_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.DATE_RECEIVED_AT_NATIONAL_LEVEL_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.DATE_RECEIVED_AT_REGION_LEVEL_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.DELETE_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.DELETE_POPUP_YES_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.DELETE_VACCINATION_REASON_POPUP_DE_VERSION; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.DISCARD_BUTTON_POPUP; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.DISEASE_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.DISEASE_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.DISEASE_VARIANT_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.DISTRICT_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.DISTRICT_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.EDIT_IMMUNIZATION_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.EDIT_REPORT_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.EDIT_TASK_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.EDIT_TRAVEL_ENTRY_FROM_CASE_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.EDIT_VACCINATION_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.EPIDEMIOLOGICAL_CONFIRMATION_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.EPID_NUMBER_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.ERROR_DESCRIPTION_REQUEST_PROCESSED; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.ERROR_IN_HANDOVER_HEADER_DE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.ERROR_REVOKE_DESCRIPTION_REQUEST_PROCESSED; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.ERROR_REVOKE_IN_HANDOVER_HEADER_DE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.EXPECTED_FOLLOWUP_LABEL; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.EXPECTED_FOLLOWUP_POPUP_TEXT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.EXPECTED_FOLLOWUP_VALUE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.EXPECTED_FOLLOW_UP_UNTIL_DATE_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.EXTERNAL_ID_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.EXTERNAL_TOKEN_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.EXTRA_COMMENT_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.FACILITY_ACTIVITY_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.FACILITY_CATEGORY_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.FACILITY_HEALTH_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.FACILITY_HEALTH_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.FACILITY_TYPE_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.FOLLOW_UP_COMMENT_FIELD; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.FOLLOW_UP_STATUS_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.FOLLOW_UP_TAB; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.FOLLOW_UP_UNTIL_DATE_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.GENERAL_COMMENT_TEXTAREA; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.GENERAL_COMMENT_TEXT_AREA; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.GENERATED_DOCUMENT_NAME; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.GENERATED_DOCUMENT_NAME_DE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.HAND_THE_OWNERSHIP_CHECKBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.HOME_BASED_QUARANTINE_POSSIBLE_OPTIONS; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.HOSPITALIZATION_TAB; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.IMMUNIZATION_CARD_IMMUNIZATION_PERIOD_LABEL; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.IMMUNIZATION_CARD_IMMUNIZATION_STATUS_LABEL; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.IMMUNIZATION_CARD_IMMUNIZATION_UUID; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.IMMUNIZATION_CARD_MANAGEMENT_STATUS_LABEL; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.IMMUNIZATION_CARD_MEANS_OF_IMMUNIZATION_LABEL; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.INFRASTRUCTURE_DATA_POPUP; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.INTERNAL_TOKEN_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.INVESTIGATED_DATE_FIELD; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.INVESTIGATION_STATUS_OPTIONS; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.LABORATORY_DIAGNOSTIC_CONFIRMATION_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.LAB_MESSAGE_WINDOW_HEADER_DE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.LINKED_EVENT_TITLE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.LINK_EVENT_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.LINK_EVENT_BUTTON_DE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.LOST_TO_FOLLOW_UP_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.NEW_IMMUNIZATION_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.NEW_SAMPLE_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.NEW_SAMPLE_BUTTON_DE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.NEW_TASK_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.NEW_TRAVEL_ENTRY_BUTTON_DE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.OFFICIAL_QUARANTINE_ORDER_SENT_CHECKBOX_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.OFFICIAL_QUARANTINE_ORDER_SENT_CHECKBOX_LABEL; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.OUTCOME_OF_CASE_OPTIONS; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.OVERWRITE_FOLLOW_UP_UNTIL_DATE_LABEL; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.PLACE_DESCRIPTION_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.PLACE_OF_STAY_CHECKBOX_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.PLACE_OF_STAY_CHECKBOX_LABEL; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.PLACE_OF_STAY_DISTRICT_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.PLACE_OF_STAY_DISTRICT_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.PLACE_OF_STAY_OPTIONS; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.PLACE_OF_STAY_REGION_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.PLACE_OF_STAY_REGION_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.PLACE_OF_STAY_SELECTED_VALUE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.POINT_OF_ENTRY_DETAILS; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.POINT_OF_ENTRY_TEXT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.POPUPS_INPUTS; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.PREGNANCY_OPTIONS; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.PROHIBITION_TO_WORK_OPTIONS; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.QUARANTINE_CHANGE_COMMENT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.QUARANTINE_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.QUARANTINE_DATE_FROM; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.QUARANTINE_DATE_FROM_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.QUARANTINE_DATE_TO; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.QUARANTINE_DATE_TO_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.QUARANTINE_ORDERED_BY_DOCUMENT_CHECKBOX_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.QUARANTINE_ORDERED_BY_DOCUMENT_CHECKBOX_LABEL; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.QUARANTINE_ORDERED_BY_DOCUMENT_DATE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.QUARANTINE_ORDERED_VERBALLY_CHECKBOX_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.QUARANTINE_ORDERED_VERBALLY_CHECKBOX_LABEL; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.QUARANTINE_ORDER_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.QUARANTINE_ORDER_POPUP_SAMPLE_FIELD; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.QUARANTINE_POPUP_DISCARD_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.QUARANTINE_POPUP_MESSAGE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.QUARANTINE_POPUP_SAVE_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.QUARANTINE_TYPE_DETAILS; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.REASON_FOR_DELETION_DETAILS_TEXTAREA; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.REFERENCE_DEFINITION_TEXT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.REFER_CASE_FROM_POINT_OF_ENTRY; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.REFER_CASE_FROM_POINT_OF_ENTRY_DISTRICT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.REFER_CASE_FROM_POINT_OF_ENTRY_POPUP_DE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.REFER_CASE_FROM_POINT_OF_ENTRY_REGION; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.REFER_CASE_FROM_POINT_OF_ENTRY_SAVE_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.REGION_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.REGION_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.REINFECTION_OPTIONS; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.REJECT_SHARED_CASE_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.REPORTER_FACILITY_DETAILS_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.REPORTER_FACILITY_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.REPORTING_TOOL_MESSAGE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.REPORT_DATE_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.REPORT_GPS_ACCURACY_IN_M_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.REPORT_GPS_LATITUDE_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.REPORT_GPS_LONGITUDE_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.RESPONSIBLE_COMMUNITY_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.RESPONSIBLE_DISTRICT_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.RESPONSIBLE_REGION_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.RESPONSIBLE_SURVEILLANCE_OFFICER_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.RESPONSIBLE_USER_FOR_FOLLOW_UP_STATUS_CHANGE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.RESPONSIBLE_USER_FOR_FOLLOW_UP_STATUS_CHANGE_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.RESUME_FOLLOW_UP_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.REVOKE_CASE_POPUP_HEADER; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.SAHRE_SAMPLES_CHECKBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.SAVE_AND_OPEN_HOSPITALIZATION_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.SAVE_POPUP_CONTENT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.SEND_TO_REPORTING_TOOL_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.SEQUELAE_DETAILS; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.SEQUELAE_OPTIONS; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.SHARE_IMMUNIZATION_CHECKBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.SHARE_ORGANIZATION_POPUP_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.SHARE_PENDING_WARNING_DE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.SHARE_REPORTS_CHECKBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.SHARE_SORMAS_2_SORMAS_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.SHOW_SAMPLE_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.SURVEILLANCE_OFFICER_FIELD_ABOVE_GENERAL_COMMENT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.SYMPTOMS_TAB; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.TRIMESTER_OPTIONS; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.UPLOAD_DOCUMENT_CHECKBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.USER_INFORMATION; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.VACCINATION_CARD_INFO_ICON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.VACCINATION_CARD_INFO_POPUP_TEXT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.VACCINATION_CARD_VACCINATION_DATE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.VACCINATION_CARD_VACCINATION_NAME; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.VACCINATION_STATUS_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.VACCINATION_STATUS_FOR_THIS_DISEASE_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.VACCINATION_STATUS_INPUT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.VACCINATION_STATUS_UPDATE_POPUP_HEADER; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.WINDOW_CLOSE_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.checkIfTextExists; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.getByImmunizationUuid; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.getEditTaskButtonByNumber; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.getPreExistingConditionComboboxToSelectValue_DE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.getPreExistingConditionComboboxWithValue_DE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.getPreExistingConditionCombobox_DE; import static org.sormas.e2etests.pages.application.cases.EpidemiologicalDataCasePage.CONTACT_TO_BODY_FLUIDS_OPTONS; import static org.sormas.e2etests.pages.application.cases.EpidemiologicalDataCasePage.CONTACT_TO_CASE_COMBOBOX; import static org.sormas.e2etests.pages.application.cases.EpidemiologicalDataCasePage.CONTINENT_COMBOBOX; @@ -2439,6 +2635,16 @@ public EditCaseSteps( webDriverHelpers.isElementEnabled( getPreExistingConditionComboboxWithValue_DE(preExistingCondition, value)))); + And( + "I select the Pre-existing condition {string} as {string} on Edit Case page", + (String preExistingCondition, String value) -> { + webDriverHelpers.scrollToElement( + getPreExistingConditionComboboxToSelectValue_DE(preExistingCondition)); + webDriverHelpers.clickWebElementByText( + getPreExistingConditionComboboxToSelectValue_DE(preExistingCondition), + value.toUpperCase()); + }); + And( "I select {string} from documents templates list", (String templateName) -> { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java index c9aa5f79687..5c6d7c6e279 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java @@ -1,20 +1,6 @@ package org.sormas.e2etests.steps.web.application.survnet; -import static org.sormas.e2etests.helpers.SchemaValidator.XMLSchemaValidator.validateXMLSchema; -import static org.sormas.e2etests.helpers.comparison.XMLComparison.compareXMLFiles; -import static org.sormas.e2etests.helpers.comparison.XMLComparison.extractDiffNodes; -import static org.sormas.e2etests.pages.application.AboutPage.SORMAS_VERSION_LINK; -import static org.sormas.e2etests.steps.web.application.cases.EditCaseSteps.externalUUID; -import static org.sormas.e2etests.steps.web.application.cases.SymptomsTabSteps.symptoms; -import static org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps.*; - import cucumber.api.java8.En; -import java.time.LocalDate; -import java.time.Period; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.List; -import javax.inject.Inject; import lombok.extern.slf4j.Slf4j; import org.jdom2.Attribute; import org.jdom2.DataConversionException; @@ -29,6 +15,22 @@ import org.sormas.e2etests.steps.web.application.persons.EditPersonSteps; import org.testng.asserts.SoftAssert; +import javax.inject.Inject; +import java.time.LocalDate; +import java.time.Period; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +import static org.sormas.e2etests.helpers.SchemaValidator.XMLSchemaValidator.validateXMLSchema; +import static org.sormas.e2etests.helpers.comparison.XMLComparison.compareXMLFiles; +import static org.sormas.e2etests.helpers.comparison.XMLComparison.extractDiffNodes; +import static org.sormas.e2etests.pages.application.AboutPage.SORMAS_VERSION_LINK; +import static org.sormas.e2etests.steps.web.application.cases.EditCaseSteps.externalUUID; +import static org.sormas.e2etests.steps.web.application.cases.SymptomsTabSteps.symptoms; +import static org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps.randomVaccinationName; +import static org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps.vaccination; + @Slf4j public class SurvNetSteps implements En { @@ -595,6 +597,80 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { "External case UUID is incorrect!"); softly.assertAll(); }); + + And( + "^I check if the Pre-existing condition \"([^\"]*)\" has \"([^\"]*)\" value mapped in SORMAS generated single XML file$", + (String disease, String value) -> { + int mappedValue = 0; + + switch (value) { + case"positive": + mappedValue = 20; + break; + case"negative": + mappedValue = 0; + break; + } + + switch (disease) { + case "diabetes": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0005"), + mappedValue, + "Diabetes mapped value is incorrect!"); + softly.assertAll(); + break; + case "immunodeficiencyIncludingHiv": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0008"), + mappedValue, + "Immunodeficiency mapped value is incorrect!"); + softly.assertAll(); + break; + case "chronicLiverDisease": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0006"), + mappedValue, + "Liver disease mapped value is incorrect!"); + softly.assertAll(); + break; + case "malignancyChemotherapy": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0011"), + mappedValue, + "Malignancy chemotherapy mapped value is incorrect!"); + softly.assertAll(); + break; + case "chronicPulmonaryDisease": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0010"), + mappedValue, + "Chronic pulmonary disease mapped value is incorrect!"); + softly.assertAll(); + break; + case "chronicKidneyDisease": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0009"), + mappedValue, + "Chronic kidney disease mapped value is incorrect!"); + softly.assertAll(); + break; + case "chronicNeurologicCondition": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0007"), + mappedValue, + "Chronic neurologic condition mapped value is incorrect!"); + softly.assertAll(); + break; + case "cardiovascularDiseaseIncludingHypertension": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0004"), + mappedValue, + "Cardiovascular disease mapped value is incorrect!"); + softly.assertAll(); + break; + } + }); } private LocalDate getReportingDate(Document xmlFile, int caseNumber) { diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature index fbe44b924d4..696c6e75010 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature @@ -250,9 +250,24 @@ Feature: Survnet tests When I click on the Cases button from navbar And I click on the NEW CASE button And I create a new case with mandatory data only for Survnet DE - Then I change all pre-existing conditions to "YES" on Edit Case page - And I navigate to case tab + And I select the Pre-existing condition "diabetes" as "Ja" on Edit Case page + And I select the Pre-existing condition "immunodeficiencyIncludingHiv" as "Ja" on Edit Case page + And I select the Pre-existing condition "chronicLiverDisease" as "Ja" on Edit Case page + And I select the Pre-existing condition "malignancyChemotherapy" as "Ja" on Edit Case page + And I select the Pre-existing condition "chronicPulmonaryDisease" as "Ja" on Edit Case page + And I select the Pre-existing condition "chronicKidneyDisease" as "Ja" on Edit Case page + And I select the Pre-existing condition "chronicNeurologicCondition" as "Ja" on Edit Case page + And I select the Pre-existing condition "cardiovascularDiseaseIncludingHypertension" as "Ja" on Edit Case page + And I click on save button from Edit Case page And I click on Send to reporting tool button on Edit Case page And I collect case external UUID from Edit Case page Then I wait 50 seconds for system reaction - And I open SORMAS generated XML file for single case message \ No newline at end of file + And I open SORMAS generated XML file for single case message + And I check if the Pre-existing condition "diabetes" has "positive" value mapped in SORMAS generated single XML file + And I check if the Pre-existing condition "immunodeficiencyIncludingHiv" has "positive" value mapped in SORMAS generated single XML file + And I check if the Pre-existing condition "chronicLiverDisease" has "positive" value mapped in SORMAS generated single XML file + And I check if the Pre-existing condition "malignancyChemotherapy" has "positive" value mapped in SORMAS generated single XML file + And I check if the Pre-existing condition "chronicPulmonaryDisease" has "positive" value mapped in SORMAS generated single XML file + And I check if the Pre-existing condition "chronicKidneyDisease" has "positive" value mapped in SORMAS generated single XML file + And I check if the Pre-existing condition "chronicNeurologicCondition" has "positive" value mapped in SORMAS generated single XML file + And I check if the Pre-existing condition "cardiovascularDiseaseIncludingHypertension" has "positive" value mapped in SORMAS generated single XML file From fa6d8648f2b1984ad8b63fd0cefeab063c90a038 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Mon, 17 Jul 2023 08:35:11 +0200 Subject: [PATCH 072/174] qu-auto/SORQA-1029 Implement "Pre-existing disease in case when sending from SORMAS to Meldesoftware". MappedValue type hase been change from int to String. --- .../steps/web/application/survnet/SurvNetSteps.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java index 5c6d7c6e279..c190c7c61d8 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java @@ -601,14 +601,14 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { And( "^I check if the Pre-existing condition \"([^\"]*)\" has \"([^\"]*)\" value mapped in SORMAS generated single XML file$", (String disease, String value) -> { - int mappedValue = 0; + String mappedValue = null; switch (value) { case"positive": - mappedValue = 20; + mappedValue = "20"; break; case"negative": - mappedValue = 0; + mappedValue = "0"; break; } From 5225141cc0c3aba0f99b557e3b40c31a655e9ff5 Mon Sep 17 00:00:00 2001 From: Razvan Date: Mon, 17 Jul 2023 09:58:06 +0300 Subject: [PATCH 073/174] SORQA-993 : added admin users into existing tests and corrections --- .../features/sanity/web/SharedCases.feature | 144 +++++++++--------- .../sanity/web/SharedContacts.feature | 40 ++--- .../features/sanity/web/SharedPersons.feature | 16 +- 3 files changed, 100 insertions(+), 100 deletions(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedCases.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedCases.feature index 261ce8c8882..f26c82f69d9 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedCases.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedCases.feature @@ -7,7 +7,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Given API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url And I check if handover card contains "Dieser Fall ist nicht geteilt" information And I collect uuid of the case @@ -17,7 +17,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup with "shared to be deleted after" Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment - And I log in as a Admin User + And I log in as a S2S And I click on the Shares button from navbar Then I accept first entity from table in Shares Page Then I navigate to "s2s_1" environment @@ -33,7 +33,7 @@ Feature: Sharing cases between environments tests And I select first created case for person from Cases list Then Total number of read only fields should be 13 And I check if handover card contains "Eigentümer: LK Fulda" information - And I check if handover card contains "Geteilt von: Automation ADMIN" information + And I check if handover card contains "Geteilt von: S2S USER" information And I check if handover card contains "shared to be deleted after" information Then I navigate to "s2s_2" environment And I click on the Cases button from navbar @@ -43,12 +43,12 @@ Feature: Sharing cases between environments tests And I select first created case for person from Cases list Then I check if editable fields are enabled for the case in view And I check if handover card contains "Gesendet von LK Barnim" information - And I check if handover card contains "Geteilt von: Automation Admin" information + And I check if handover card contains "Geteilt von: S2S User" information And I check if handover card contains "shared to be deleted after" information @tmsLink=SORDEV-13953 @env_s2s_1 Scenario: S2S - Share a case that was Archived - Given I log in as a Admin User + Given I log in as a S2S When I click on the Cases button from navbar Then I click on the NEW CASE button And I fill a new case form for DE version with mandatory data with "Berlin" as a region and "SK Berlin Mitte" as a district @@ -62,7 +62,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab - When I log in as a Admin User + When I log in as a S2S And I click on the Shares button from navbar And I click on "accept" shared case button with copied case description And I open the last created case with collected UUID by url on "s2s_2" instance @@ -77,7 +77,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Then API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S And I open the last created Case via API Then I click on save button in the case popup And I click NEW VACCINATION button for DE @@ -104,7 +104,7 @@ Feature: Sharing cases between environments tests And I fill new vaccination data in new Vaccination form for DE with "Comirnaty (COVID-19-mRNA Impfstoff)" as a vaccine name And I click SAVE button in new Vaccination form Then I navigate to "s2s_2" environment in new driver tab - And I log in as a Admin User + And I log in as a S2S And I click on the Shares button from navbar And I click on "accept" shared case button with copied case description Then I open last created Case via API on "s2s_2" instance @@ -120,7 +120,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Then API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S And I open the last created Case via API Then I click on save button in the case popup And I click NEW VACCINATION button for DE @@ -137,7 +137,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab - And I log in as a Admin User + And I log in as a S2S And I click on the Shares button from navbar And I click on "accept" shared case button with copied case description Then I back to tab number 1 @@ -159,7 +159,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Then API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S And I open the last created Case via API Then I click on save button in the case popup And I click NEW VACCINATION button for DE @@ -176,7 +176,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab - And I log in as a Admin User + And I log in as a S2S And I click on the Shares button from navbar And I click on "accept" shared case button with copied case description Then I open last created Case via API on "s2s_2" instance @@ -200,7 +200,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Then API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S And I open the last created Case via API Then I click on share case button And I select organization to share with "s2s_2" @@ -217,7 +217,7 @@ Feature: Sharing cases between environments tests And I save the created sample with pathogen test And I open the last created Case via API Then I navigate to "s2s_2" environment in new driver tab - And I log in as a Admin User + And I log in as a S2S And I click on the Shares button from navbar And I click on "accept" shared case button with copied case description And I click on the Cases button from navbar @@ -234,7 +234,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Then API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S And I open the last created Case via API Then I click on save button in the case popup And I click NEW VACCINATION button for DE @@ -252,7 +252,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab - And I log in as a Admin User + And I log in as a S2S And I click on the Shares button from navbar And I click on "accept" shared case button with copied case description And I click on the Cases button from navbar @@ -280,7 +280,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Then API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S And I open the last created Case via API Then I click on save button in the case popup And I click NEW VACCINATION button for DE @@ -298,7 +298,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab - And I log in as a Admin User + And I log in as a S2S And I click on the Shares button from navbar And I click on "accept" shared case button with copied case description And I click on the Cases button from navbar @@ -326,7 +326,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Then API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S And I open the last created Case via API Then I click on save button in the case popup And I click NEW VACCINATION button for DE @@ -344,7 +344,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab - And I log in as a Admin User + And I log in as a S2S And I click on the Shares button from navbar And I click on "accept" shared case button with copied case description And I click on the Cases button from navbar @@ -372,7 +372,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Then API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S And I open the last created Case via API When I open the Case Contacts tab Then I click on new contact button from Case Contacts tab @@ -383,7 +383,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar And I accept first entity from table in Shares Page Then I back to tab number 1 @@ -411,7 +411,7 @@ Feature: Sharing cases between environments tests @tmsLink=SORDEV-12449 @env_s2s_1 Scenario: S2S_added sample after sharing a case/contact does not get shared [1] - Given I log in as a Admin User + Given I log in as a S2S And I click on the Cases button from navbar And I click on the NEW CASE button Then I create a new case with specific person name and "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district for DE version @@ -428,7 +428,7 @@ Feature: Sharing cases between environments tests And I create a new Sample with only required fields for DE version And I click on save sample button Then I navigate to "s2s_2" environment in new driver tab - And I log in as a Admin User + And I log in as a S2S And I click on the Shares button from navbar Then I accept first entity from table in Shares Page And I click on the The Eye Icon located in the Shares Page @@ -437,13 +437,13 @@ Feature: Sharing cases between environments tests @tmsLink=SORDEV-12094 @env_s2s_1 Scenario: [S2S] Mergen with hand over the ownership - merge for source system - Given I log in as a Admin User + Given I log in as a S2S And I click on the Cases button from navbar And I click on the NEW CASE button Then I create a new case with specific person name and "Hessen" region and "LK Fulda" district for DE version Then I click on save button in the case popup Then I navigate to "s2s_2" environment in new driver tab - And I log in as a Admin User + And I log in as a S2S And I click on the Cases button from navbar And I click on the NEW CASE button Then I create a new case with specific person name and "Hessen" region and "LK Fulda" district for DE version @@ -468,13 +468,13 @@ Feature: Sharing cases between environments tests @tmsLink=SORDEV-12094 @env_s2s_1 Scenario: [S2S] Mergen with hand over the ownership - merge for target system - Given I log in as a Admin User + Given I log in as a S2S And I click on the Cases button from navbar And I click on the NEW CASE button Then I create a new case with specific person name and "Hessen" region and "LK Fulda" district for DE version Then I click on save button in the case popup Then I navigate to "s2s_2" environment in new driver tab - And I log in as a Admin User + And I log in as a S2S And I click on the Cases button from navbar And I click on the NEW CASE button Then I create a new case with specific person name and "Hessen" region and "LK Fulda" district for DE version @@ -499,13 +499,13 @@ Feature: Sharing cases between environments tests @tmsLink=SORDEV-12094 @env_s2s_1 Scenario: [S2S] Mergen without hand over the ownership - Given I log in as a Admin User + Given I log in as a S2S And I click on the Cases button from navbar And I click on the NEW CASE button Then I create a new case with mandatory data with person name and "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district for DE version Then I click on save button in the case popup Then I navigate to "s2s_2" environment in new driver tab - And I log in as a Admin User + And I log in as a S2S And I click on the Cases button from navbar And I click on the NEW CASE button Then I create a new case with mandatory data with person name and "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district for DE version @@ -535,7 +535,7 @@ Feature: Sharing cases between environments tests Scenario: S2S_Processed lab messages should be transferred [2] Given API : Login to DEMIS server Then I create and send Laboratory Notification - And I log in as a Admin User + And I log in as a S2S Then I click on the Messages button from navbar And I click on fetch messages button Then I filter by last created person via API in Messages Directory @@ -557,7 +557,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_3" environment in new driver tab - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar And I click on "accept" shared case button with copied case description And I click on the Cases button from navbar @@ -577,7 +577,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Then API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S And I open the last created Case via API When I open the Case Contacts tab Then I click on new contact button from Case Contacts tab @@ -609,7 +609,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar And I click on "accept" shared case button with copied case description @@ -619,7 +619,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Then API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S And I open the last created Case via API When I open the Case Contacts tab Then I click on new contact button from Case Contacts tab @@ -651,7 +651,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar And I click on "accept" shared case button with copied case description Then I back to tab number 1 @@ -667,7 +667,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Then API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S And I open the last created Case via API When I open the Case Contacts tab Then I click on new contact button from Case Contacts tab @@ -700,7 +700,7 @@ Feature: Sharing cases between environments tests And I click to hand over the ownership of the case in Share popup Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar And I click on "accept" shared contact button with copied contact description @@ -710,7 +710,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Then API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S And I open the last created Case via API When I open the Case Contacts tab Then I click on new contact button from Case Contacts tab @@ -743,7 +743,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup for contact with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar And I click on "accept" shared contact button with copied contact description Then I back to tab number 1 @@ -759,7 +759,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Then API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S And I open the last created Case via API When I open the Case Contacts tab Then I click on new contact button from Case Contacts tab @@ -771,7 +771,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar And I click on the The Eye Icon located in the Shares Page And I check that "KONTAKT-ID" column header is not visible in Share request details window for DE @@ -782,7 +782,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Then API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S And I open the last created Case via API When I open the Case Contacts tab Then I click on new contact button from Case Contacts tab @@ -793,7 +793,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar And I accept first entity from table in Shares Page Then I back to tab number 1 @@ -815,7 +815,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Given API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case Then I click on share case button @@ -823,7 +823,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar And I click on "reject" shared case button with copied case description Then I fill comment field in Reject share request popup and click confirm @@ -837,7 +837,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Given API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case Then I click on share case button @@ -845,7 +845,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar And I click on "accept" shared case button with copied case description Then I back to tab number 1 @@ -859,7 +859,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Given API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case Then I click on share case button @@ -867,7 +867,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar And I click on "reject" shared case button with copied case description Then I fill comment field in Reject share request popup and click confirm @@ -887,7 +887,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Given API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case Then I click on share case button @@ -896,7 +896,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar And I click on "accept" shared case button with copied case description Then I navigate to "s2s_1" environment @@ -909,7 +909,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Given API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case Then I click on share case button @@ -918,7 +918,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar Then I back to tab number 1 And I click on revoke share button @@ -933,7 +933,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Given API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case Then I click on share case button @@ -942,7 +942,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar Then I back to tab number 1 And I click on revoke share button @@ -956,7 +956,7 @@ Feature: Sharing cases between environments tests Scenario: S2S_Processed lab messages should be transferred [1] Given API : Login to DEMIS server Then I create and send Laboratory Notification - And I log in as a Admin User + And I log in as a S2S Then I click on the Messages button from navbar And I click on fetch messages button Then I filter by last created person via API in Messages Directory @@ -979,7 +979,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_3" environment in new driver tab - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar And I click on "accept" shared case button with copied case description And I click on the Cases button from navbar @@ -999,7 +999,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Given API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case Then I click on share case button @@ -1008,7 +1008,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar Then I accept first entity from table in Shares Page Then I navigate to "s2s_1" environment @@ -1039,7 +1039,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Given API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case Then I click on share case button @@ -1048,7 +1048,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar Then I accept first entity from table in Shares Page And I click on the Cases button from navbar @@ -1070,7 +1070,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Given API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case Then I click on share case button @@ -1078,7 +1078,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment - And I log in as a Admin User + And I log in as a S2S And I click on the Shares button from navbar Then I accept first entity from table in Shares Page Then I navigate to "s2s_1" environment @@ -1100,7 +1100,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Given API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case Then I click on share case button @@ -1108,7 +1108,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar Then I accept first entity from table in Shares Page And I click on the Cases button from navbar @@ -1133,7 +1133,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Given API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url Then I click on share case button And I select organization to share with "s2s_2" @@ -1143,7 +1143,7 @@ Feature: Sharing cases between environments tests And I set Reason for deletion as "Löschen auf Anforderung der betroffenen Person nach DSGVO" And I click on Yes option in Confirm deletion popup Then I navigate to "s2s_2" environment - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar And I click on the The Eye Icon located in the Shares Page Then I check that first shared result has different id then deleted shared case @@ -1154,7 +1154,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Given API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case Then I click on share case button @@ -1162,7 +1162,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar Then I click on the The Eye Icon located in the Shares Page And I check if received case id is equal with sent @@ -1173,7 +1173,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 And API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case Then I click on share case button @@ -1181,7 +1181,7 @@ Feature: Sharing cases between environments tests And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar And I check that accept shared case button with copied case description is visible in Share Directory page Then I back to tab number 1 diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedContacts.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedContacts.feature index d0306f95609..54e6e896a37 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedContacts.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedContacts.feature @@ -7,7 +7,7 @@ Feature: Sharing contacts between environments tests And API: I check that POST call status code is 200 Then API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Then I log in as a Admin User + Then I log in as a S2S When I click on the Contacts button from navbar And I click on the NEW CONTACT button And I fill a new contact form for DE version with mandatory data with "Baden-Württemberg" as a region and "LK Alb-Donau-Kreis" as a disctrict @@ -37,7 +37,7 @@ Feature: Sharing contacts between environments tests And I fill comment in share popup for contact with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab - And I log in as a Admin User + And I log in as a S2S And I click on the Shares button from navbar And I click on "accept" shared contact button with copied contact description Then I check if a warning pop-up message appears that the Case should be accepted first @@ -52,7 +52,7 @@ Feature: Sharing contacts between environments tests And API: I check that POST call status code is 200 Then API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Then I log in as a Admin User + Then I log in as a S2S When I click on the Contacts button from navbar And I click on the NEW CONTACT button And I fill a new contact form for DE version with mandatory data with "Baden-Württemberg" as a region and "LK Alb-Donau-Kreis" as a disctrict @@ -97,7 +97,7 @@ Feature: Sharing contacts between environments tests And API: I check that POST call status code is 200 Given API: I create a new contact with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district linked to last created case And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case Then I click on share case button @@ -105,7 +105,7 @@ Feature: Sharing contacts between environments tests And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar Then I accept first entity from table in Shares Page Then I navigate to "s2s_1" environment @@ -142,7 +142,7 @@ Feature: Sharing contacts between environments tests And API: I check that POST call status code is 200 Given API: I create a new contact with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district linked to last created case And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case Then I click on share case button @@ -150,7 +150,7 @@ Feature: Sharing contacts between environments tests And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar Then I accept first entity from table in Shares Page Then I navigate to "s2s_1" environment @@ -184,7 +184,7 @@ Feature: Sharing contacts between environments tests And API: I check that POST call status code is 200 Given API: I create a new contact with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district linked to last created case And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case Then I click on share case button @@ -192,7 +192,7 @@ Feature: Sharing contacts between environments tests And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar Then I accept first entity from table in Shares Page Then I navigate to "s2s_1" environment @@ -226,7 +226,7 @@ Feature: Sharing contacts between environments tests And API: I check that POST call status code is 200 Given API: I create a new contact with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district linked to last created case And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case Then I click on share case button @@ -234,7 +234,7 @@ Feature: Sharing contacts between environments tests And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar Then I accept first entity from table in Shares Page Then I navigate to "s2s_1" environment @@ -269,14 +269,14 @@ Feature: Sharing contacts between environments tests And API: I check that POST call status code is 200 Given API: I create a new contact with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district linked to last created case And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url Then I click on share case button And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar Then I accept first entity from table in Shares Page Then I navigate to "s2s_1" environment @@ -302,7 +302,7 @@ Feature: Sharing contacts between environments tests And API: I check that POST call status code is 200 Given API: I create a new contact with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district linked to last created case And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case Then I click on share case button @@ -311,7 +311,7 @@ Feature: Sharing contacts between environments tests And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar Then I accept first entity from table in Shares Page Then I navigate to "s2s_1" environment @@ -334,12 +334,12 @@ Feature: Sharing contacts between environments tests Then I open the last created contact via API And I check if editable fields are read only for shared contact And I check if handover card contains "Eigentümer: LK Fulda" information - And I check if handover card contains "Geteilt von: Automation ADMIN" information + And I check if handover card contains "Geteilt von: S2S USER" information And I check if handover card contains "shared with automated test" information Then I navigate to "s2s_2" environment Then I open the last created contact via API And I check if handover card contains "Gesendet von LK Barnim" information - And I check if handover card contains "Geteilt von: Automation Admin" information + And I check if handover card contains "Geteilt von: S2S User" information And I check if handover card contains "shared with automated test" information @tmsLink=SOR-4483 @env_s2s_1 @@ -350,7 +350,7 @@ Feature: Sharing contacts between environments tests And API: I check that POST call status code is 200 Given API: I create a new contact with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district linked to last created case And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case Then I click on share case button @@ -359,7 +359,7 @@ Feature: Sharing contacts between environments tests And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar And I check that accept shared case button with copied case description is visible in Share Directory page Then I accept first entity from table in Shares Page @@ -372,7 +372,7 @@ Feature: Sharing contacts between environments tests And I fill comment in share popup for contact with random string Then I click on share button in s2s share popup and wait for share to finish And I check if handover card contains "LK Fulda" information - And I check if handover card contains "Geteilt von: Automation ADMIN" information + And I check if handover card contains "Geteilt von: S2S USER" information Then I back to tab number 2 And I refresh current page And I check that accept shared contact button with copied contact description is visible in Share Directory page diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedPersons.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedPersons.feature index 83840774e58..84409aee27a 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedPersons.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedPersons.feature @@ -9,7 +9,7 @@ Feature: Sharing persons between environments tests And API: I check that POST call status code is 200 Given API: I create a new contact with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district linked to last created case And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case Then I click on share case button @@ -18,7 +18,7 @@ Feature: Sharing persons between environments tests And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish And I navigate to "s2s_2" environment in new driver tab - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar Then I accept first entity from table in Shares Page When I back to tab number 1 @@ -50,7 +50,7 @@ Feature: Sharing persons between environments tests And API: I check that POST call status code is 200 Given API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case Then I click on share case button @@ -59,7 +59,7 @@ Feature: Sharing persons between environments tests And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish And I navigate to "s2s_2" environment in new driver tab - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar Then I accept first entity from table in Shares Page And I click on the Cases button from navbar @@ -75,7 +75,7 @@ Feature: Sharing persons between environments tests @tmsLink=SORDEV-12088 @env_s2s_1 Scenario: [S2S] Simultaneous Work on Person [3] - Given I log in as a Admin User + Given I log in as a S2S And I click on the Cases button from navbar And I click on the NEW CASE button And I fill new case data for duplicates merge with for one person data for DE @@ -86,7 +86,7 @@ Feature: Sharing persons between environments tests And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish And I navigate to "s2s_2" environment in new driver tab - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar Then I accept first entity from table in Shares Page And I click on the The Eye Icon located in the Shares Page @@ -128,7 +128,7 @@ Feature: Sharing persons between environments tests And API: I check that POST call status code is 200 Given API: I create a new case with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district and "General Hospital" facility And API: I check that POST call status code is 200 - Given I log in as a Admin User + Given I log in as a S2S And I click on the Contacts button from navbar And I click on the NEW CONTACT button And I fill a new contact form with same person data with "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district for DE version @@ -145,7 +145,7 @@ Feature: Sharing persons between environments tests And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish And I navigate to "s2s_2" environment in new driver tab - Given I log in as a Admin User + Given I log in as a S2S And I click on the Shares button from navbar Then I accept first entity from table in Shares Page When I back to tab number 1 From b4060c43dd0446f6a5d731c026756ef5843d762e Mon Sep 17 00:00:00 2001 From: Razvan Date: Mon, 17 Jul 2023 10:00:55 +0300 Subject: [PATCH 074/174] SORQA-993 :fix for tomek --- .../java/org/sormas/e2etests/webdriver/RemoteDriverFactory.java | 1 + 1 file changed, 1 insertion(+) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/webdriver/RemoteDriverFactory.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/webdriver/RemoteDriverFactory.java index 3b6d0f3f521..67bd0d914fd 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/webdriver/RemoteDriverFactory.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/webdriver/RemoteDriverFactory.java @@ -77,6 +77,7 @@ public ChromeDriver getRemoteWebDriver() { options.setExperimentalOption("prefs", chromePreferences); options.addArguments("--window-size=1920,1080"); options.setPageLoadStrategy(PageLoadStrategy.NORMAL); + options.addArguments("--remote-allow-origins=*"); return new ChromeDriver(options); } From 484b2d80954fb8e531cf4f36106ede6adb5f27ef Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Mon, 17 Jul 2023 09:04:24 +0200 Subject: [PATCH 075/174] qu-auto/SORQA-1029 Implement "Pre-existing disease in case when sending from SORMAS to Meldesoftware". Structure of the BDD test scenario has been changed. --- .../features/sanity/web/Survnet.feature | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature index 696c6e75010..d49d9dd34ad 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature @@ -245,29 +245,35 @@ Feature: Survnet tests And I check if Vaccine name in SORMAS generated XML file is correct @tmsLink=SORQA-1029 - Scenario: Pre-existing disease in case when sending from SORMAS to Meldesoftware + Scenario Outline: Pre-existing disease in case when sending from SORMAS to Meldesoftware Given I log in as a Survnet When I click on the Cases button from navbar And I click on the NEW CASE button And I create a new case with mandatory data only for Survnet DE And I select the Pre-existing condition "diabetes" as "Ja" on Edit Case page - And I select the Pre-existing condition "immunodeficiencyIncludingHiv" as "Ja" on Edit Case page - And I select the Pre-existing condition "chronicLiverDisease" as "Ja" on Edit Case page - And I select the Pre-existing condition "malignancyChemotherapy" as "Ja" on Edit Case page - And I select the Pre-existing condition "chronicPulmonaryDisease" as "Ja" on Edit Case page - And I select the Pre-existing condition "chronicKidneyDisease" as "Ja" on Edit Case page - And I select the Pre-existing condition "chronicNeurologicCondition" as "Ja" on Edit Case page - And I select the Pre-existing condition "cardiovascularDiseaseIncludingHypertension" as "Ja" on Edit Case page + And I select the Pre-existing condition "immunodeficiencyIncludingHiv" as
+ + org.geotools + gt-shapefile + + org.hibernate hibernate-core @@ -214,11 +219,6 @@ ${project.version} - - org.geotools - gt-shapefile - - diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index 78661993d29..a5e6e7c6f13 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -778,6 +778,13 @@
+ + org.geotools + gt-shapefile + 28.2 + provided + + org.hibernate hibernate-core @@ -1186,16 +1193,6 @@ - - org.geotools - gt-shapefile - 28.2 - - - diff --git a/sormas-serverlibs/pom.xml b/sormas-serverlibs/pom.xml index e803227c873..f468ceb89e8 100644 --- a/sormas-serverlibs/pom.xml +++ b/sormas-serverlibs/pom.xml @@ -188,6 +188,11 @@ docx4j-JAXB-ReferenceImpl + + org.geotools + gt-shapefile + + org.hibernate hibernate-core From 5c69d9924c57888b2c1910e658d9bd5bd3835f3e Mon Sep 17 00:00:00 2001 From: Stefan Kock Date: Thu, 20 Jul 2023 15:18:02 +0200 Subject: [PATCH 104/174] #12094 Bump gt-shapefile from 28.2 to 29.2 in /sormas-base Bumps org.geotools:gt-shapefile from 28.2 to 29.2. --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index a5e6e7c6f13..66c7ef5036c 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -781,7 +781,7 @@ org.geotools gt-shapefile - 28.2 + 29.2 provided From 51790b4f7a60ea585cfea14088b25e44f1755444 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Jul 2023 17:10:37 +0000 Subject: [PATCH 105/174] Bump netty.version from 4.1.94.Final to 4.1.95.Final in /sormas-base Bumps `netty.version` from 4.1.94.Final to 4.1.95.Final. Updates `io.netty:netty-codec-http2` from 4.1.94.Final to 4.1.95.Final - [Commits](https://github.com/netty/netty/compare/netty-4.1.94.Final...netty-4.1.95.Final) Updates `io.netty:netty-handler-proxy` from 4.1.94.Final to 4.1.95.Final - [Commits](https://github.com/netty/netty/compare/netty-4.1.94.Final...netty-4.1.95.Final) Updates `io.netty:netty-transport-native-epoll:linux-x86_64` from 4.1.94.Final to 4.1.95.Final - [Commits](https://github.com/netty/netty/compare/netty-4.1.94.Final...netty-4.1.95.Final) Updates `io.netty:netty-transport-native-unix-common` from 4.1.94.Final to 4.1.95.Final - [Commits](https://github.com/netty/netty/compare/netty-4.1.94.Final...netty-4.1.95.Final) --- updated-dependencies: - dependency-name: io.netty:netty-codec-http2 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.netty:netty-handler-proxy dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.netty:netty-transport-native-epoll:linux-x86_64 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.netty:netty-transport-native-unix-common dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index 66c7ef5036c..b57a794ee83 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -37,7 +37,7 @@ 1.70 1.56.1 21.0.1 - 4.1.94.Final + 4.1.95.Final 5.0.7.Final 1.9.0 2.0.4 From 8252c30a00bcf7600353d7d394d0cd256c62cbea Mon Sep 17 00:00:00 2001 From: sormas-vitagroup Date: Fri, 21 Jul 2023 09:10:57 +0000 Subject: [PATCH 106/174] [GitHub Actions] Update openAPI spec files --- sormas-rest/swagger.json | 6 ++---- sormas-rest/swagger.yaml | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/sormas-rest/swagger.json b/sormas-rest/swagger.json index a5d4d3b0883..84142ff473e 100644 --- a/sormas-rest/swagger.json +++ b/sormas-rest/swagger.json @@ -17324,10 +17324,8 @@ "maxLength" : 255, "minLength" : 0 }, - "personCountryIsoCode" : { - "type" : "string", - "maxLength" : 255, - "minLength" : 0 + "personCountry" : { + "$ref" : "#/components/schemas/CountryReferenceDto" }, "personEmail" : { "type" : "string", diff --git a/sormas-rest/swagger.yaml b/sormas-rest/swagger.yaml index a03cc0b2c4b..b76a7d71992 100644 --- a/sormas-rest/swagger.yaml +++ b/sormas-rest/swagger.yaml @@ -15959,10 +15959,8 @@ components: type: string maxLength: 255 minLength: 0 - personCountryIsoCode: - type: string - maxLength: 255 - minLength: 0 + personCountry: + $ref: '#/components/schemas/CountryReferenceDto' personEmail: type: string maxLength: 255 From 0e8418d60af040e6709d3712f70ccce23a179055 Mon Sep 17 00:00:00 2001 From: Razvan Date: Fri, 21 Jul 2023 23:16:01 +0300 Subject: [PATCH 107/174] SOR-4648 : code fixes --- .../src/main/java/recorders/StepsLogger.java | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/recorders/StepsLogger.java b/sormas-e2e-tests/src/main/java/recorders/StepsLogger.java index bcd7678e61b..c3573ab185e 100644 --- a/sormas-e2e-tests/src/main/java/recorders/StepsLogger.java +++ b/sormas-e2e-tests/src/main/java/recorders/StepsLogger.java @@ -48,8 +48,8 @@ public class StepsLogger implements StepLifecycleListener { private static RemoteWebDriver driver; private static boolean isScreenshotEnabled = true; private static boolean takeScreenshotAfterStep = false; - private final String pngValue = "png"; - private final String imageType = "image/png"; + private final String jpgExtension = "jpg"; + private final String imageType = "image/jpg"; public static void setRemoteWebDriver(RemoteWebDriver remoteWebDriver) { driver = remoteWebDriver; @@ -72,7 +72,7 @@ public void afterStepUpdate(final StepResult stepResult) { List uiWarnings = collectWarningElements(); if (!uiWarnings.isEmpty()) { for (InputStream input : collectWarningElements()) { - Allure.getLifecycle().addAttachment("Warning element", imageType, pngValue, input); + Allure.getLifecycle().addAttachment("Warning element", imageType, jpgExtension, input); } } boolean logData = false; @@ -101,30 +101,28 @@ private void attachConsoleLog() { } } - @Attachment(value = "After step screenshot", type = "image/png") + @Attachment(value = "After step screenshot", type = "image/jpg") public void takeScreenshot() { byte[] screenShot = driver.getScreenshotAs(OutputType.BYTES); Allure.getLifecycle() .addAttachment( "Screenshot at :" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("dd-MMM-yy hh:mm:ss")), - "image/png", - "png", + "image/jpg", + "jpg", screenShot); } @SneakyThrows private List collectWarningElements() { List warningsList = - driver.findElements( - By.xpath( - "//*[contains(@class,'Notification error') or contains(@class,'filterselect-required') or contains(@class,'field-required') or contains(@class,'group-required')]")); + driver.findElements(By.xpath("//*[contains(@class,'error')]")); List attachments = new ArrayList<>(); - String fileName = "warning_element%s.png"; + String fileName = "warning_element%s.jpg"; for (int i = 0; i < warningsList.size(); i++) { - String file = String.format(fileName, i) + "." + pngValue; + String file = String.format(fileName, i) + "." + jpgExtension; Screenshot screenshot = new AShot().takeScreenshot(driver, warningsList.get(i)); - ImageIO.write(screenshot.getImage(), pngValue.toUpperCase(), new File("build\\" + file)); + ImageIO.write(screenshot.getImage(), jpgExtension.toUpperCase(), new File("build\\" + file)); attachments.add(new FileInputStream("build\\" + file)); } return attachments; From 771763fd8d0e1235775a69ad4399b667ef7228ef Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Mon, 24 Jul 2023 08:45:05 +0200 Subject: [PATCH 108/174] qu-auto/SORQA-980 Demis - Process a Lab message that has multiple pathogen test in a sample --- .../resources/features/sanity/web/DemisWeb.feature | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index 89d55b70c76..71a7aec701b 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -565,4 +565,13 @@ Scenario: Create and send laboratory request via Demis And I filter by last created person via API in Messages Directory And I verify that status for result 1 is set to processed in Message Directory page And I click on the eye icon next for the first fetched message - And I check if external message window appears and close it \ No newline at end of file + And I check if external message window appears and close it + + @tmsLink=SORQA-980 @env_d2s @LoginKeycloak + Scenario: Demis - Process a Lab message that has multiple pathogen test in a sample + Given API : Login to DEMIS server + When I create and send Laboratory Notification with one existing facility + And I log in as a Admin User + And I click on the Messages button from navbar + And I click on fetch messages button + And I filter by last created person via API in Messages Directory \ No newline at end of file From 2cb3f0032ccaace2d8dd7d97b65b05e067ab3223 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 14:18:33 +0000 Subject: [PATCH 109/174] Bump osgi-resource-locator from 1.0.3 to 2.4.0 in /sormas-base Bumps osgi-resource-locator from 1.0.3 to 2.4.0. --- updated-dependencies: - dependency-name: org.glassfish.hk2:osgi-resource-locator dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index b57a794ee83..d926950deca 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -253,7 +253,7 @@ org.glassfish.hk2 osgi-resource-locator - 1.0.3 + 2.4.0 provided From 1e6bb71d76accf917d7a45e1902fc3eb3d0939a0 Mon Sep 17 00:00:00 2001 From: Martin Wahnschaffe Date: Fri, 14 Jul 2023 10:13:40 +0200 Subject: [PATCH 110/174] Revert "Bump osgi-resource-locator from 1.0.3 to 2.4.0 in /sormas-base" This reverts commit 1aabcf2dfd7e5f16565f1d8c9db98c069baee6c9. --- sormas-base/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index d926950deca..b57a794ee83 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -253,7 +253,7 @@ org.glassfish.hk2 osgi-resource-locator - 2.4.0 + 1.0.3 provided From 07845b716ff0823c356cdc5e6085f758fab2cab3 Mon Sep 17 00:00:00 2001 From: Martin Wahnschaffe Date: Fri, 14 Jul 2023 10:15:01 +0200 Subject: [PATCH 111/174] #12150 added hk2 glassfish dependencies to dependabot ignore list --- .github/dependabot.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 8f8db37ea06..b5ebd22d92e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -34,6 +34,8 @@ updates: - dependency-name: org.eclipse.microprofile.config:microprofile-config-api - dependency-name: org.glassfish:javax.el - dependency-name: org.glassfish.corba:glassfish-corba-omgapi + - dependency-name: org.glassfish.hk2:* + - dependency-name: org.glassfish.hk2.*:* - dependency-name: org.glassfish.jaxb:* - dependency-name: org.glassfish.jersey*:jersey-* - dependency-name: org.glassfish.soteria:javax.security.enterprise From c44bce40d8dd4015e277f2ef165c3535586fdae9 Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Mon, 24 Jul 2023 20:47:52 +0300 Subject: [PATCH 112/174] #12025 - Add an environment list for the mobile app --- sormas-app/app/src/main/AndroidManifest.xml | 8 + .../de/symeda/sormas/app/BaseActivity.java | 9 + .../app/backend/common/AbstractAdoDao.java | 4 +- .../app/backend/common/DatabaseHelper.java | 17 +- .../common/DtoFeatureConfigHelper.java | 4 + .../app/backend/environment/Environment.java | 380 +++++++++--------- .../environment/EnvironmentCriteria.java | 18 + .../backend/environment/EnvironmentDao.java | 87 +++- .../environment/EnvironmentDtoHelper.java | 160 ++++---- .../dialog/SynchronizationDialog.java | 8 + .../list/EnvironmentListActivity.java | 129 ++++++ .../list/EnvironmentListAdapter.java | 27 ++ .../list/EnvironmentListFragment.java | 58 +++ .../list/EnvironmentListViewModel.java | 108 +++++ .../app/rest/EnvironmentFacadeRetro.java | 20 +- .../sormas/app/rest/SynchronizeDataAsync.java | 37 +- .../sormas/app/util/DateFormatHelper.java | 9 + .../sormas/app/util/NavigationHelper.java | 5 + .../ic_drawer_environment_blue_36dp.xml | 5 + .../layout/filter_environment_list_layout.xml | 76 ++++ .../row_environment_list_item_layout.xml | 165 ++++++++ .../src/main/res/menu/drawer_main_menu.xml | 14 +- .../app/src/main/res/values/strings.xml | 4 + .../environment/EnvironmentService.java | 12 + .../rest/resources/EnvironmentResource.java | 6 + 25 files changed, 1073 insertions(+), 297 deletions(-) create mode 100644 sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/EnvironmentCriteria.java create mode 100644 sormas-app/app/src/main/java/de/symeda/sormas/app/environment/list/EnvironmentListActivity.java create mode 100644 sormas-app/app/src/main/java/de/symeda/sormas/app/environment/list/EnvironmentListAdapter.java create mode 100644 sormas-app/app/src/main/java/de/symeda/sormas/app/environment/list/EnvironmentListFragment.java create mode 100644 sormas-app/app/src/main/java/de/symeda/sormas/app/environment/list/EnvironmentListViewModel.java create mode 100644 sormas-app/app/src/main/res/drawable/ic_drawer_environment_blue_36dp.xml create mode 100644 sormas-app/app/src/main/res/layout/filter_environment_list_layout.xml create mode 100644 sormas-app/app/src/main/res/layout/row_environment_list_item_layout.xml diff --git a/sormas-app/app/src/main/AndroidManifest.xml b/sormas-app/app/src/main/AndroidManifest.xml index 098a3733816..dd51fb07bb1 100644 --- a/sormas-app/app/src/main/AndroidManifest.xml +++ b/sormas-app/app/src/main/AndroidManifest.xml @@ -422,6 +422,14 @@ android:screenOrientation="portrait" android:launchMode="singleTop"> + + + + diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/BaseActivity.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/BaseActivity.java index a6aa75baf22..6f37ecafdde 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/BaseActivity.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/BaseActivity.java @@ -306,6 +306,8 @@ public boolean onNavigationItemSelected(MenuItem item) { NavigationHelper.goToEvents(getContext()); } else if (id == R.id.menu_item_samples) { NavigationHelper.goToSamples(getContext()); + } else if (id == R.id.menu_item_environments) { + NavigationHelper.goToEnvironments(getContext()); } else if (id == R.id.menu_item_immunizations) { NavigationHelper.goToImmunizations(getContext()); } else if (id == R.id.menu_item_campaigns) { @@ -410,6 +412,7 @@ private void setupDrawer(NavigationView navView) { MenuItem contactMenu = menuNav.findItem(R.id.menu_item_contacts); MenuItem eventMenu = menuNav.findItem(R.id.menu_item_events); MenuItem sampleMenu = menuNav.findItem(R.id.menu_item_samples); + MenuItem environmentMenu = menuNav.findItem(R.id.menu_item_environments); MenuItem immunizationMenu = menuNav.findItem(R.id.menu_item_immunizations); MenuItem reportMenu = menuNav.findItem(R.id.menu_item_reports); MenuItem campaignMenu = menuNav.findItem(R.id.menu_item_campaigns); @@ -438,6 +441,12 @@ private void setupDrawer(NavigationView navView) { ConfigProvider.hasUserRight(UserRight.SAMPLE_VIEW) && !DatabaseHelper.getFeatureConfigurationDao().isFeatureDisabled(FeatureType.SAMPLES_LAB)); + if (environmentMenu != null) { + environmentMenu.setVisible( + ConfigProvider.hasUserRight(UserRight.ENVIRONMENT_VIEW) + && !DatabaseHelper.getFeatureConfigurationDao().isFeatureDisabled(FeatureType.ENVIRONMENT_MANAGEMENT)); + } + if (immunizationMenu != null) immunizationMenu.setVisible( ConfigProvider.hasUserRight(UserRight.IMMUNIZATION_VIEW) diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AbstractAdoDao.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AbstractAdoDao.java index 0fd7dee49db..d84868466f8 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AbstractAdoDao.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AbstractAdoDao.java @@ -50,6 +50,7 @@ import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.app.R; import de.symeda.sormas.app.backend.caze.Case; +import de.symeda.sormas.app.backend.environment.Environment; import de.symeda.sormas.app.backend.feature.FeatureConfiguration; import de.symeda.sormas.app.component.dialog.SynchronizationDialog; import de.symeda.sormas.app.util.MetaProperty; @@ -676,7 +677,8 @@ public ADO mergeOrCreate(ADO source) throws DaoException { || parentProperty.equals(property.getName()) || property.getReadMethod().isAnnotationPresent(JoinTableReference.class) || Case.COMPLETENESS.equals(property.getName()) - || FeatureConfiguration.PROPERTIES_MAP.equals(property.getName())) + || FeatureConfiguration.PROPERTIES_MAP.equals(property.getName()) + || Environment.WATER_USE.equals(property.getName())) continue; // we now have to write the value from source into target and base diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java index 8fc183b685e..66dd667ae0b 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java @@ -93,6 +93,8 @@ import de.symeda.sormas.app.backend.customizableenum.CustomizableEnumValueDao; import de.symeda.sormas.app.backend.disease.DiseaseConfiguration; import de.symeda.sormas.app.backend.disease.DiseaseConfigurationDao; +import de.symeda.sormas.app.backend.environment.Environment; +import de.symeda.sormas.app.backend.environment.EnvironmentDao; import de.symeda.sormas.app.backend.epidata.EpiData; import de.symeda.sormas.app.backend.epidata.EpiDataDao; import de.symeda.sormas.app.backend.event.Event; @@ -263,6 +265,7 @@ public static void clearTables(boolean clearInfrastructure) { TableUtils.clearTable(connectionSource, DiseaseClassificationCriteria.class); TableUtils.clearTable(connectionSource, CampaignFormData.class); TableUtils.clearTable(connectionSource, LbdsSync.class); + TableUtils.clearTable(connectionSource, Environment.class); if (clearInfrastructure) { TableUtils.clearTable(connectionSource, UserUserRole.class); @@ -368,6 +371,7 @@ public void onCreate(SQLiteDatabase db, ConnectionSource connectionSource) { TableUtils.createTable(connectionSource, CampaignFormData.class); TableUtils.createTable(connectionSource, CampaignFormMeta.class); TableUtils.createTable(connectionSource, LbdsSync.class); + TableUtils.createTable(connectionSource, Environment.class); } catch (SQLException e) { Log.e(DatabaseHelper.class.getName(), "Can't build database", e); throw new RuntimeException(e); @@ -3050,10 +3054,10 @@ public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int case 344: currentVersion = 344; - getDao(DiseaseConfiguration.class).executeRaw( - "CREATE TABLE environments(id integer primary key autoincrement, uuid VARCHAR(36) NOT NULL, " + getDao(Environment.class).executeRaw( + "CREATE TABLE environments(id integer primary key autoincrement, uuid VARCHAR(36) NOT NULL UNIQUE, " + "changeDate TIMESTAMP NOT NULL, creationDate TIMESTAMP NOT NULL, lastOpenedDate TIMESTAMP, localChangeDate TIMESTAMP NOT NULL, modified INTEGER, " - + "snapshot INTEGER, reportDate TIMESTAMP, reportingUser_id BIGINT REFERENCES users(id), environmentName text, description text, " + + "snapshot INTEGER, reportDate TIMESTAMP NOT NULL, reportingUser_id BIGINT REFERENCES users(id), environmentName text, description text, " + "externalId varchar(255), responsibleUser_id BIGINT REFERENCES users(id), investigationStatus varchar(255), environmentMedia varchar(255), " + "waterType varchar(255), otherWaterType text, infrastructureDetails varchar(255), otherInfrastructureDetails text, waterUse text, " + "otherWaterUse text, location_id BIGINT, UNIQUE(snapshot, uuid));"); @@ -3863,6 +3867,7 @@ private void upgradeFromUnupgradableVersion(SQLiteDatabase db, ConnectionSource TableUtils.dropTable(connectionSource, CampaignFormMeta.class, true); TableUtils.dropTable(connectionSource, CampaignFormData.class, true); TableUtils.dropTable(connectionSource, LbdsSync.class, true); + TableUtils.dropTable(connectionSource, Environment.class, true); if (oldVersion < 30) { TableUtils.dropTable(connectionSource, Config.class, true); @@ -3988,6 +3993,8 @@ public AbstractAdoDao getAdoDaoInner(Cla dao = (AbstractAdoDao) new CampaignFormMetaDao((Dao) innerDao); } else if (type.equals(CampaignFormData.class)) { dao = (AbstractAdoDao) new CampaignFormDataDao((Dao) innerDao); + } else if (type.equals(Environment.class)) { + dao = (AbstractAdoDao) new EnvironmentDao((Dao) innerDao); } else { throw new UnsupportedOperationException(type.toString()); } @@ -4261,6 +4268,10 @@ public static CampaignFormDataDao getCampaignFormDataDao() { return (CampaignFormDataDao) getAdoDao(CampaignFormData.class); } + public static EnvironmentDao getEnvironmentDao() { + return (EnvironmentDao) getAdoDao(Environment.class); + } + /** * Close the database connections and clear any cached DAOs. */ diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DtoFeatureConfigHelper.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DtoFeatureConfigHelper.java index 9a981bb256f..a44718ce71b 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DtoFeatureConfigHelper.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DtoFeatureConfigHelper.java @@ -79,4 +79,8 @@ public static boolean isFeatureConfigForTreatmentsEnabled() { public static boolean isFeatureConfigForClinicalVisitsEnabled() { return DatabaseHelper.getFeatureConfigurationDao().isFeatureEnabled(FeatureType.CLINICAL_MANAGEMENT); } + + public static boolean isFeatureConfigForEnvironmentEnabled() { + return DatabaseHelper.getFeatureConfigurationDao().isFeatureEnabled(FeatureType.ENVIRONMENT_MANAGEMENT); + } } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/Environment.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/Environment.java index 12a5ace97b3..a1dc71b7c56 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/Environment.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/Environment.java @@ -1,23 +1,22 @@ package de.symeda.sormas.app.backend.environment; -import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_BIG; import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_DEFAULT; -import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_SMALL; import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_TEXT; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.j256.ormlite.field.DataType; import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; import java.lang.reflect.Type; import java.util.Date; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.persistence.Column; +import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; @@ -26,200 +25,207 @@ import de.symeda.sormas.api.environment.EnvironmentMedia; import de.symeda.sormas.api.environment.WaterType; import de.symeda.sormas.api.environment.WaterUse; -import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.app.backend.common.AbstractDomainObject; import de.symeda.sormas.app.backend.location.Location; import de.symeda.sormas.app.backend.user.User; +@Entity(name = Environment.TABLE_NAME) +@DatabaseTable(tableName = Environment.TABLE_NAME) public class Environment extends AbstractDomainObject { - public static final String TABLE_NAME = "environments"; - public static final String I18N_PREFIX = "Environment"; - - public static final String REPORT_DATE = "reportDate"; - public static final String REPORTING_USER = "reportingUser"; - public static final String ENVIRONMENT_NAME = "environmentName"; - public static final String DESCRIPTION = "description"; - public static final String EXTERNAL_ID = "externalId"; - public static final String RESPONSIBLE_USER = "responsibleUser"; - public static final String INVESTIGATION_STATUS = "investigationStatus"; - public static final String ENVIRONMENT_MEDIA = "environmentMedia"; - public static final String WATER_TYPE = "waterType"; - public static final String OTHER_WATER_TYPE = "otherWaterType"; - public static final String INFRASTUCTURE_DETAILS = "infrastructureDetails"; - public static final String OTHER_INFRASTRUCTUIRE_DETAILS = "otherInfrastructureDetails"; - public static final String WATER_DRINKING_HOUSEHOLD = "waterUseDrinkingHousehold"; - public static final String WATER_USE = "waterUse"; - public static final String OTHER_WATER_USE = "otherWaterUse"; - public static final String LOCATION = "location"; - - @DatabaseField(dataType = DataType.DATE_LONG) - private Date reportDate; - @DatabaseField(foreign = true, foreignAutoRefresh = true, columnName = "reportingUser_id") - private User reportingUser; - @Column(length = CHARACTER_LIMIT_TEXT) - private String environmentName; - @Column(length = CHARACTER_LIMIT_TEXT) - private String description; - @Column(length = CHARACTER_LIMIT_DEFAULT) - private String externalId; - @DatabaseField(foreign = true, foreignAutoRefresh = true, columnName = "responsibleUser_id") - private User responsibleUser; - @Enumerated(EnumType.STRING) - private InvestigationStatus investigationStatus; - @Enumerated(EnumType.STRING) - private EnvironmentMedia environmentMedia; - @Enumerated(EnumType.STRING) - private WaterType waterType; - @Column(length = CHARACTER_LIMIT_TEXT) - private String otherWaterType; - @Enumerated(EnumType.STRING) - private EnvironmentInfrastructureDetails infrastructureDetails; - @Column(length = CHARACTER_LIMIT_TEXT) - private String otherInfrastructureDetails; - @Column(name = "waterUse", length = 1024) - private String waterUseJson; - private Map waterUse; - @Column(length = CHARACTER_LIMIT_TEXT) - private String otherWaterUse; - @DatabaseField(foreign = true, foreignAutoRefresh = true, maxForeignAutoRefreshLevel = 2) - private Location location; - - public Date getReportDate() { - return reportDate; - } - - public void setReportDate(Date reportDate) { - this.reportDate = reportDate; - } - - public User getReportingUser() { - return reportingUser; - } - - public void setReportingUser(User reportingUser) { - this.reportingUser = reportingUser; - } - - public String getEnvironmentName() { - return environmentName; - } - - public void setEnvironmentName(String environmentName) { - this.environmentName = environmentName; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getExternalId() { - return externalId; - } - - public void setExternalId(String externalId) { - this.externalId = externalId; - } - - public User getResponsibleUser() { - return responsibleUser; - } - - public void setResponsibleUser(User responsibleUser) { - this.responsibleUser = responsibleUser; - } - - public InvestigationStatus getInvestigationStatus() { - return investigationStatus; - } - - public void setInvestigationStatus(InvestigationStatus investigationStatus) { - this.investigationStatus = investigationStatus; - } - - public EnvironmentMedia getEnvironmentMedia() { - return environmentMedia; - } - - public void setEnvironmentMedia(EnvironmentMedia environmentMedia) { - this.environmentMedia = environmentMedia; - } - - public WaterType getWaterType() { - return waterType; - } - - public void setWaterType(WaterType waterType) { - this.waterType = waterType; - } - - public String getOtherWaterType() { - return otherWaterType; - } - - public void setOtherWaterType(String otherWaterType) { - this.otherWaterType = otherWaterType; - } - - public EnvironmentInfrastructureDetails getInfrastructureDetails() { - return infrastructureDetails; - } - - public void setInfrastructureDetails(EnvironmentInfrastructureDetails infrastructureDetails) { - this.infrastructureDetails = infrastructureDetails; - } - - public String getOtherInfrastructureDetails() { - return otherInfrastructureDetails; - } - - public void setOtherInfrastructureDetails(String otherInfrastructureDetails) { - this.otherInfrastructureDetails = otherInfrastructureDetails; - } - - public String getWaterUseJson() { - return waterUseJson; - } + public static final String TABLE_NAME = "environments"; + public static final String I18N_PREFIX = "Environment"; + + public static final String REPORT_DATE = "reportDate"; + public static final String REPORTING_USER = "reportingUser"; + public static final String ENVIRONMENT_NAME = "environmentName"; + public static final String DESCRIPTION = "description"; + public static final String EXTERNAL_ID = "externalId"; + public static final String RESPONSIBLE_USER = "responsibleUser"; + public static final String INVESTIGATION_STATUS = "investigationStatus"; + public static final String ENVIRONMENT_MEDIA = "environmentMedia"; + public static final String WATER_TYPE = "waterType"; + public static final String OTHER_WATER_TYPE = "otherWaterType"; + public static final String INFRASTUCTURE_DETAILS = "infrastructureDetails"; + public static final String OTHER_INFRASTRUCTUIRE_DETAILS = "otherInfrastructureDetails"; + public static final String WATER_DRINKING_HOUSEHOLD = "waterUseDrinkingHousehold"; + public static final String WATER_USE = "wateruse"; + public static final String OTHER_WATER_USE = "otherWaterUse"; + public static final String LOCATION = "location"; + + @DatabaseField(dataType = DataType.DATE_LONG) + private Date reportDate; + @DatabaseField(foreign = true, foreignAutoRefresh = true, columnName = "reportingUser_id") + private User reportingUser; + @Column(length = CHARACTER_LIMIT_TEXT) + private String environmentName; + @Column(length = CHARACTER_LIMIT_TEXT) + private String description; + @Column(length = CHARACTER_LIMIT_DEFAULT) + private String externalId; + @DatabaseField(foreign = true, foreignAutoRefresh = true, columnName = "responsibleUser_id") + private User responsibleUser; + @Enumerated(EnumType.STRING) + private InvestigationStatus investigationStatus; + @Enumerated(EnumType.STRING) + private EnvironmentMedia environmentMedia; + @Enumerated(EnumType.STRING) + private WaterType waterType; + @Column(length = CHARACTER_LIMIT_TEXT) + private String otherWaterType; + @Enumerated(EnumType.STRING) + private EnvironmentInfrastructureDetails infrastructureDetails; + @Column(length = CHARACTER_LIMIT_TEXT) + private String otherInfrastructureDetails; + @Column(name = "wateruse", length = 1024) + private String waterUseJson; + private Map wateruse; + @Column(length = CHARACTER_LIMIT_TEXT) + private String otherWaterUse; + @DatabaseField(foreign = true, foreignAutoRefresh = true, maxForeignAutoRefreshLevel = 2) + private Location location; + + @Override + public String getI18nPrefix() { + return I18N_PREFIX; + } + + public Date getReportDate() { + return reportDate; + } + + public void setReportDate(Date reportDate) { + this.reportDate = reportDate; + } + + public User getReportingUser() { + return reportingUser; + } + + public void setReportingUser(User reportingUser) { + this.reportingUser = reportingUser; + } + + public String getEnvironmentName() { + return environmentName; + } + + public void setEnvironmentName(String environmentName) { + this.environmentName = environmentName; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getExternalId() { + return externalId; + } + + public void setExternalId(String externalId) { + this.externalId = externalId; + } + + public User getResponsibleUser() { + return responsibleUser; + } + + public void setResponsibleUser(User responsibleUser) { + this.responsibleUser = responsibleUser; + } + + public InvestigationStatus getInvestigationStatus() { + return investigationStatus; + } + + public void setInvestigationStatus(InvestigationStatus investigationStatus) { + this.investigationStatus = investigationStatus; + } + + public EnvironmentMedia getEnvironmentMedia() { + return environmentMedia; + } + + public void setEnvironmentMedia(EnvironmentMedia environmentMedia) { + this.environmentMedia = environmentMedia; + } + + public WaterType getWaterType() { + return waterType; + } + + public void setWaterType(WaterType waterType) { + this.waterType = waterType; + } + + public String getOtherWaterType() { + return otherWaterType; + } + + public void setOtherWaterType(String otherWaterType) { + this.otherWaterType = otherWaterType; + } + + public EnvironmentInfrastructureDetails getInfrastructureDetails() { + return infrastructureDetails; + } + + public void setInfrastructureDetails(EnvironmentInfrastructureDetails infrastructureDetails) { + this.infrastructureDetails = infrastructureDetails; + } + + public String getOtherInfrastructureDetails() { + return otherInfrastructureDetails; + } - public void setWaterUseJson(String waterUseJson) { - this.waterUseJson = waterUseJson; - waterUse = null; - } + public void setOtherInfrastructureDetails(String otherInfrastructureDetails) { + this.otherInfrastructureDetails = otherInfrastructureDetails; + } - public Map getWaterUse() { - if (waterUse == null) { + public String getWaterUseJson() { + return waterUseJson; + } + + public void setWaterUseJson(String waterUseJson) { + this.waterUseJson = waterUseJson; + } + + public Map getWateruse() { + if (wateruse == null) { Gson gson = new Gson(); - Type type = new TypeToken>() { + Type type = new TypeToken>() { }.getType(); - waterUse = gson.fromJson(waterUseJson, type); - if (waterUse == null) { - waterUse = new HashMap<>(); + wateruse = gson.fromJson(waterUseJson, type); + if (wateruse == null) { + wateruse = new HashMap<>(); } } - return waterUse; - } - - public void setWaterUse(Map waterUse) { - this.waterUse = waterUse; - } - - public String getOtherWaterUse() { - return otherWaterUse; - } - - public void setOtherWaterUse(String otherWaterUse) { - this.otherWaterUse = otherWaterUse; - } - - public Location getLocation() { - return location; - } - - public void setLocation(Location location) { - this.location = location; - } + return wateruse; + } + + public void setWateruse(Map wateruse) { + this.wateruse = wateruse; + Gson gson = new Gson(); + waterUseJson = gson.toJson(wateruse); + } + + public String getOtherWaterUse() { + return otherWaterUse; + } + + public void setOtherWaterUse(String otherWaterUse) { + this.otherWaterUse = otherWaterUse; + } + + public Location getLocation() { + return location; + } + + public void setLocation(Location location) { + this.location = location; + } } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/EnvironmentCriteria.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/EnvironmentCriteria.java new file mode 100644 index 00000000000..19a6d3a0740 --- /dev/null +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/EnvironmentCriteria.java @@ -0,0 +1,18 @@ +package de.symeda.sormas.app.backend.environment; + +import java.io.Serializable; + +import de.symeda.sormas.api.caze.InvestigationStatus; + +public class EnvironmentCriteria implements Serializable { + + private InvestigationStatus investigationStatus; + + public InvestigationStatus getInvestigationStatus() { + return investigationStatus; + } + + public void setInvestigationStatus(InvestigationStatus investigationStatus) { + this.investigationStatus = investigationStatus; + } +} diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/EnvironmentDao.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/EnvironmentDao.java index 1b73ceefc15..9960a9efaa0 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/EnvironmentDao.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/EnvironmentDao.java @@ -1,24 +1,87 @@ package de.symeda.sormas.app.backend.environment; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + import com.j256.ormlite.dao.Dao; +import com.j256.ormlite.stmt.QueryBuilder; +import com.j256.ormlite.stmt.Where; -import java.sql.SQLException; +import android.util.Log; import de.symeda.sormas.app.backend.common.AbstractAdoDao; +import de.symeda.sormas.app.backend.common.AbstractDomainObject; public class EnvironmentDao extends AbstractAdoDao { - public EnvironmentDao(Dao innerDao) throws SQLException { - super(innerDao); - } + public EnvironmentDao(Dao innerDao) throws SQLException { + super(innerDao); + } + + @Override + protected Class getAdoClass() { + return Environment.class; + } + + @Override + public String getTableName() { + return Environment.TABLE_NAME; + } + + public List getAll() { + try { + QueryBuilder queryBuilder = queryBuilder(); + return queryBuilder.orderBy(Environment.CHANGE_DATE, false).query(); + } catch (SQLException e) { + Log.e(getTableName(), "Could not perform getAllActive on Environment"); + throw new RuntimeException(); + } + } + + public long countByCriteria(EnvironmentCriteria criteria) { + try { + return buildQueryBuilder(criteria).countOf(); + } catch (SQLException e) { + Log.e(getTableName(), "Could not perform countByCriteria on Environment"); + throw new RuntimeException(); + } + } + + public List queryByCriteria(EnvironmentCriteria criteria, long offset, long limit) { + try { + return buildQueryBuilder(criteria).orderBy(Environment.LOCAL_CHANGE_DATE, false).offset(offset).limit(limit).query(); + } catch (SQLException e) { + Log.e(getTableName(), "Could not perform queryByCriteria on Environment"); + throw new RuntimeException(); + } + } + + private QueryBuilder buildQueryBuilder(EnvironmentCriteria criteria) throws SQLException { + QueryBuilder queryBuilder = queryBuilder(); + List> whereStatements = new ArrayList<>(); + Where where = queryBuilder.where(); + whereStatements.add(where.eq(AbstractDomainObject.SNAPSHOT, false)); + + addEqualsCriteria(whereStatements, where, criteria.getInvestigationStatus(), Environment.INVESTIGATION_STATUS); + + if (!whereStatements.isEmpty()) { + Where whereStatement = where.and(whereStatements.size()); + queryBuilder.setWhere(whereStatement); + } + + return queryBuilder; + } + + public void deleteEnvironmentAndAllDependingEntities(String environmentUuid) throws SQLException { + Environment environment = queryUuidWithEmbedded(environmentUuid); - @Override - protected Class getAdoClass() { - return Environment.class; - } + // Cancel if not in local database + if (environment == null) { + return; + } - @Override - public String getTableName() { - return Environment.TABLE_NAME; - } + // Delete case + deleteCascade(environment); + } } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/EnvironmentDtoHelper.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/EnvironmentDtoHelper.java index f213a1fce10..bdb6433ca65 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/EnvironmentDtoHelper.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/EnvironmentDtoHelper.java @@ -4,10 +4,8 @@ import de.symeda.sormas.api.PostResponse; import de.symeda.sormas.api.environment.EnvironmentDto; -import de.symeda.sormas.api.event.EventDto; import de.symeda.sormas.app.backend.common.AdoDtoHelper; import de.symeda.sormas.app.backend.common.DatabaseHelper; -import de.symeda.sormas.app.backend.event.Event; import de.symeda.sormas.app.backend.location.Location; import de.symeda.sormas.app.backend.location.LocationDtoHelper; import de.symeda.sormas.app.backend.user.User; @@ -18,94 +16,94 @@ public class EnvironmentDtoHelper extends AdoDtoHelper { - private LocationDtoHelper locationHelper; + private LocationDtoHelper locationHelper; - public EnvironmentDtoHelper() { - this.locationHelper = new LocationDtoHelper();; - } + public EnvironmentDtoHelper() { + this.locationHelper = new LocationDtoHelper();; + } - @Override - protected Class getAdoClass() { - return Environment.class; - } + @Override + protected Class getAdoClass() { + return Environment.class; + } - @Override - protected Class getDtoClass() { - return EnvironmentDto.class; - } + @Override + protected Class getDtoClass() { + return EnvironmentDto.class; + } - @Override - protected Call> pullAllSince(long since, Integer size, String lastSynchronizedUuid) throws NoConnectionException { - return RetroProvider.getEnvironmentFacade().pullAllSince(since); - } + @Override + protected Call> pullAllSince(long since, Integer size, String lastSynchronizedUuid) throws NoConnectionException { + return RetroProvider.getEnvironmentFacade().pullAllSince(since); + } - @Override - protected Call> pullByUuids(List uuids) throws NoConnectionException { - return RetroProvider.getEnvironmentFacade().pullByUuids(uuids); - } + @Override + protected Call> pullByUuids(List uuids) throws NoConnectionException { + return RetroProvider.getEnvironmentFacade().pullByUuids(uuids); + } - @Override - protected Call> pushAll(List environmentDtos) throws NoConnectionException { - return RetroProvider.getEnvironmentFacade().pushAll(environmentDtos); - } + @Override + protected Call> pushAll(List environmentDtos) throws NoConnectionException { + return RetroProvider.getEnvironmentFacade().pushAll(environmentDtos); + } - @Override - protected void fillInnerFromDto(Environment target, EnvironmentDto source) { + @Override + protected void fillInnerFromDto(Environment target, EnvironmentDto source) { - target.setReportDate(source.getReportDate()); - target.setReportingUser(DatabaseHelper.getUserDao().getByReferenceDto(source.getReportingUser())); - target.setEnvironmentName(source.getEnvironmentName()); - target.setDescription(source.getDescription()); - target.setExternalId(source.getExternalId()); - target.setResponsibleUser(DatabaseHelper.getUserDao().getByReferenceDto(source.getResponsibleUser())); - target.setInvestigationStatus(source.getInvestigationStatus()); - target.setEnvironmentMedia(source.getEnvironmentMedia()); - target.setWaterType(source.getWaterType()); - target.setOtherWaterType(source.getOtherWaterType()); - target.setInfrastructureDetails(source.getInfrastructureDetails()); - target.setOtherInfrastructureDetails(source.getOtherInfrastructureDetails()); - target.setWaterType(source.getWaterType()); - target.setOtherWaterUse(source.getOtherWaterUse()); - target.setLocation(locationHelper.fillOrCreateFromDto(target.getLocation(), source.getLocation())); - } + target.setReportDate(source.getReportDate()); + target.setReportingUser(DatabaseHelper.getUserDao().getByReferenceDto(source.getReportingUser())); + target.setEnvironmentName(source.getEnvironmentName()); + target.setDescription(source.getDescription()); + target.setExternalId(source.getExternalId()); + target.setResponsibleUser(DatabaseHelper.getUserDao().getByReferenceDto(source.getResponsibleUser())); + target.setInvestigationStatus(source.getInvestigationStatus()); + target.setEnvironmentMedia(source.getEnvironmentMedia()); + target.setWaterType(source.getWaterType()); + target.setOtherWaterType(source.getOtherWaterType()); + target.setInfrastructureDetails(source.getInfrastructureDetails()); + target.setOtherInfrastructureDetails(source.getOtherInfrastructureDetails()); + target.setWateruse(source.getWaterUse()); + target.setOtherWaterUse(source.getOtherWaterUse()); + target.setLocation(locationHelper.fillOrCreateFromDto(target.getLocation(), source.getLocation())); + } - @Override - protected void fillInnerFromAdo(EnvironmentDto target, Environment source) { + @Override + protected void fillInnerFromAdo(EnvironmentDto target, Environment source) { - target.setReportDate(source.getReportDate()); - if (source.getReportingUser() != null) { - User user = DatabaseHelper.getUserDao().queryForId(source.getReportingUser().getId()); - target.setReportingUser(UserDtoHelper.toReferenceDto(user)); - } else { - target.setReportingUser(null); - } - target.setEnvironmentName(source.getEnvironmentName()); - target.setDescription(source.getDescription()); - target.setExternalId(source.getExternalId()); - if (source.getResponsibleUser() != null) { - User user = DatabaseHelper.getUserDao().queryForId(source.getResponsibleUser().getId()); - target.setResponsibleUser(UserDtoHelper.toReferenceDto(user)); - } else { - target.setResponsibleUser(null); - } - target.setInvestigationStatus(source.getInvestigationStatus()); - target.setEnvironmentMedia(source.getEnvironmentMedia()); - target.setWaterType(source.getWaterType()); - target.setOtherWaterType(source.getOtherWaterType()); - target.setInfrastructureDetails(source.getInfrastructureDetails()); - target.setOtherInfrastructureDetails(source.getOtherInfrastructureDetails()); - target.setWaterType(source.getWaterType()); - target.setOtherWaterUse(source.getOtherWaterUse()); - if (source.getLocation() != null) { - Location location = DatabaseHelper.getLocationDao().queryForId(source.getLocation().getId()); - target.setLocation(locationHelper.adoToDto(location)); - } else { - target.setLocation(null); - } - } + target.setReportDate(source.getReportDate()); + if (source.getReportingUser() != null) { + User user = DatabaseHelper.getUserDao().queryForId(source.getReportingUser().getId()); + target.setReportingUser(UserDtoHelper.toReferenceDto(user)); + } else { + target.setReportingUser(null); + } + target.setEnvironmentName(source.getEnvironmentName()); + target.setDescription(source.getDescription()); + target.setExternalId(source.getExternalId()); + if (source.getResponsibleUser() != null) { + User user = DatabaseHelper.getUserDao().queryForId(source.getResponsibleUser().getId()); + target.setResponsibleUser(UserDtoHelper.toReferenceDto(user)); + } else { + target.setResponsibleUser(null); + } + target.setInvestigationStatus(source.getInvestigationStatus()); + target.setEnvironmentMedia(source.getEnvironmentMedia()); + target.setWaterType(source.getWaterType()); + target.setOtherWaterType(source.getOtherWaterType()); + target.setInfrastructureDetails(source.getInfrastructureDetails()); + target.setOtherInfrastructureDetails(source.getOtherInfrastructureDetails()); + target.setWaterUse(source.getWateruse()); + target.setOtherWaterUse(source.getOtherWaterUse()); + if (source.getLocation() != null) { + Location location = DatabaseHelper.getLocationDao().queryForId(source.getLocation().getId()); + target.setLocation(locationHelper.adoToDto(location)); + } else { + target.setLocation(null); + } + } - @Override - protected long getApproximateJsonSizeInBytes() { - return EnvironmentDto.APPROXIMATE_JSON_SIZE_IN_BYTES; - } + @Override + protected long getApproximateJsonSizeInBytes() { + return EnvironmentDto.APPROXIMATE_JSON_SIZE_IN_BYTES; + } } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/component/dialog/SynchronizationDialog.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/component/dialog/SynchronizationDialog.java index bd5c452763c..aedfd55e837 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/component/dialog/SynchronizationDialog.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/component/dialog/SynchronizationDialog.java @@ -26,6 +26,7 @@ import de.symeda.sormas.api.contact.ContactDto; import de.symeda.sormas.api.customizableenum.CustomizableEnumValueDto; import de.symeda.sormas.api.disease.DiseaseConfigurationDto; +import de.symeda.sormas.api.environment.EnvironmentDto; import de.symeda.sormas.api.event.EventDto; import de.symeda.sormas.api.event.EventParticipantDto; import de.symeda.sormas.api.feature.FeatureConfigurationDto; @@ -320,6 +321,7 @@ private void showDeleteObsoleteProgressItems() { addEntityIfViewAllowed(EventParticipantDto.class, Strings.entityEventParticipants, allowedEntities); addEntityIfViewAllowed(ImmunizationDto.class, Strings.entityImmunizations, allowedEntities); addEntityIfViewAllowed(SampleDto.class, Strings.entitySamples, allowedEntities); + addEntityIfViewAllowed(EnvironmentDto.class, Strings.entityEnvironment, allowedEntities); addEntityIfViewAllowed(TaskDto.class, Strings.entityTasks, allowedEntities); addEntityIfViewAllowed(OutbreakDto.class, Strings.entityOutbreaks, allowedEntities); addEntityIfViewAllowed(AggregateReportDto.class, Strings.entityAggregateReports, allowedEntities); @@ -335,6 +337,7 @@ private void showPushNewProgressItems() { addEntityIfEditAllowed(EventDto.class, Strings.entityEvents, allowedEntities); addEntityIfEditAllowed(EventParticipantDto.class, Strings.entityEventParticipants, allowedEntities); addEntityIfEditAllowed(SampleDto.class, Strings.entitySamples, allowedEntities); + addEntityIfEditAllowed(EnvironmentDto.class, Strings.entityEnvironment, allowedEntities); addEntityIfEditAllowed(PathogenTestDto.class, Strings.entityPathogenTests, allowedEntities); addEntityIfEditAllowed(AdditionalTestDto.class, Strings.entityAdditionalTests, allowedEntities); addEntityIfEditAllowed(ContactDto.class, Strings.entityContacts, allowedEntities); @@ -367,6 +370,7 @@ private void showRepullProgressItems() { addEntityIfViewAllowed(EventDto.class, Strings.entityEvents, allowedEntities); addEntityIfViewAllowed(EventParticipantDto.class, Strings.entityEventParticipants, allowedEntities); addEntityIfViewAllowed(SampleDto.class, Strings.entitySamples, allowedEntities); + addEntityIfViewAllowed(EnvironmentDto.class, Strings.entityEnvironment, allowedEntities); addEntityIfViewAllowed(PathogenTestDto.class, Strings.entityPathogenTests, allowedEntities); addEntityIfViewAllowed(AdditionalTestDto.class, Strings.entityAdditionalTests, allowedEntities); addEntityIfViewAllowed(ContactDto.class, Strings.entityContacts, allowedEntities); @@ -392,6 +396,7 @@ private void showSynchronizeProgressItems() { addEntityIfViewOrEditAllowed(EventDto.class, Strings.entityEvents, allowedEntities); addEntityIfViewOrEditAllowed(EventParticipantDto.class, Strings.entityEventParticipants, allowedEntities); addEntityIfViewOrEditAllowed(SampleDto.class, Strings.entitySamples, allowedEntities); + addEntityIfViewOrEditAllowed(EnvironmentDto.class, Strings.entityEnvironment, allowedEntities); addEntityIfViewOrEditAllowed(PathogenTestDto.class, Strings.entityPathogenTests, allowedEntities); addEntityIfViewOrEditAllowed(AdditionalTestDto.class, Strings.entityAdditionalTests, allowedEntities); addEntityIfViewOrEditAllowed(ContactDto.class, Strings.entityContacts, allowedEntities); @@ -419,6 +424,8 @@ private void showPullModifiedProgressItems() { addEntityIfViewAllowed(EventParticipantDto.class, Strings.entityEventParticipants, allowedEntities); if (DtoFeatureConfigHelper.isFeatureConfigForSampleEnabled()) addEntityIfViewAllowed(SampleDto.class, Strings.entitySamples, allowedEntities); + if (DtoFeatureConfigHelper.isFeatureConfigForEnvironmentEnabled()) + addEntityIfViewAllowed(EnvironmentDto.class, Strings.entityEnvironment, allowedEntities); if (DtoFeatureConfigHelper.isFeatureConfigForSampleTestsEnabled()) addEntityIfViewAllowed(PathogenTestDto.class, Strings.entityPathogenTests, allowedEntities); if (DtoFeatureConfigHelper.isFeatureConfigForAdditionalTestsEnabled()) @@ -456,6 +463,7 @@ private void showClearUpProgressItems(boolean forDeletion) { addEntityIfViewAllowed(EventDto.class, Strings.entityEvents, allowedEntities); addEntityIfViewAllowed(EventParticipantDto.class, Strings.entityEventParticipants, allowedEntities); addEntityIfViewAllowed(SampleDto.class, Strings.entitySamples, allowedEntities); + addEntityIfViewAllowed(EnvironmentDto.class, Strings.entityEnvironment, allowedEntities); addEntityIfViewAllowed(PathogenTestDto.class, Strings.entityPathogenTests, allowedEntities); addEntityIfViewAllowed(AdditionalTestDto.class, Strings.entityAdditionalTests, allowedEntities); addEntityIfViewAllowed(ContactDto.class, Strings.entityContacts, allowedEntities); diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/environment/list/EnvironmentListActivity.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/environment/list/EnvironmentListActivity.java new file mode 100644 index 00000000000..afa675f2ee0 --- /dev/null +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/environment/list/EnvironmentListActivity.java @@ -0,0 +1,129 @@ +package de.symeda.sormas.app.environment.list; + +import java.util.List; + +import android.content.Context; +import android.os.Bundle; +import android.view.View; + +import androidx.databinding.DataBindingUtil; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.RecyclerView; + +import de.symeda.sormas.api.caze.InvestigationStatus; +import de.symeda.sormas.app.BaseListActivity; +import de.symeda.sormas.app.PagedBaseListActivity; +import de.symeda.sormas.app.PagedBaseListFragment; +import de.symeda.sormas.app.R; +import de.symeda.sormas.app.backend.common.DatabaseHelper; +import de.symeda.sormas.app.backend.environment.Environment; +import de.symeda.sormas.app.component.Item; +import de.symeda.sormas.app.component.menu.PageMenuItem; +import de.symeda.sormas.app.databinding.FilterEnvironmentListLayoutBinding; +import de.symeda.sormas.app.util.Callback; +import de.symeda.sormas.app.util.DataUtils; + +public class EnvironmentListActivity extends PagedBaseListActivity { + + private EnvironmentListViewModel model; + + private FilterEnvironmentListLayoutBinding filterBinding; + + public static void startActivity(Context context) { + List environments = DatabaseHelper.getEnvironmentDao().getAll(); + int pageMenuPosition = environments.size() > 0 ? 1 : 0; + BaseListActivity.startActivity(context, EnvironmentListActivity.class, buildBundle(pageMenuPosition)); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + showPreloader(); + adapter = new EnvironmentListAdapter(); + adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { + + @Override + public void onItemRangeInserted(int positionStart, int itemCount) { + if (positionStart == 0) { + RecyclerView recyclerView = findViewById(R.id.recyclerViewForList); + if (recyclerView != null) { + recyclerView.scrollToPosition(0); + } + } + } + + @Override + public void onItemRangeMoved(int positionStart, int toPosition, int itemCount) { + RecyclerView recyclerView = findViewById(R.id.recyclerViewForList); + if (recyclerView != null) { + recyclerView.scrollToPosition(0); + } + } + + }); + + model = new ViewModelProvider(this).get(EnvironmentListViewModel.class); + model.initializeViewModel(); + model.getEnvironmentList().observe(this, environments -> { + adapter.submitList(environments); + hidePreloader(); + }); + + filterBinding.setCriteria(model.getEnvironmentCriteria()); + + setOpenPageCallback(pageMenuItem -> { + showPreloader(); + model.notifyCriteriaUpdated(); + }); + } + + @Override + public void onPause() { + super.onPause(); + getIntent().putExtra("refreshOnResume", true); + } + + @Override + protected int getActivityTitle() { + return R.string.heading_environments_list; + } + + @Override + public void addFiltersToPageMenu() { + View environmentListFilterView = getLayoutInflater().inflate(R.layout.filter_environment_list_layout, null); + filterBinding = DataBindingUtil.bind(environmentListFilterView); + + List environementInvestigationStatuses = DataUtils.getEnumItems(InvestigationStatus.class); + filterBinding.investigationStatusFilter.initializeSpinner(environementInvestigationStatuses); + + pageMenu.addFilter(environmentListFilterView); + + filterBinding.applyFilters.setOnClickListener(e -> { + showPreloader(); + pageMenu.hideAll(); + model.notifyCriteriaUpdated(); + }); + + filterBinding.resetFilters.setOnClickListener(e -> { + showPreloader(); + pageMenu.hideAll(); + model.getEnvironmentCriteria().setInvestigationStatus(null); + filterBinding.invalidateAll(); + model.notifyCriteriaUpdated(); + }); + } + + @Override + protected Callback getSynchronizeResultCallback() { + return () -> { + showPreloader(); + model.getEnvironmentList().getValue().getDataSource().invalidate(); + }; + } + + @Override + protected PagedBaseListFragment buildListFragment(PageMenuItem menuItem) { + return EnvironmentListFragment.newInstance(); + } +} diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/environment/list/EnvironmentListAdapter.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/environment/list/EnvironmentListAdapter.java new file mode 100644 index 00000000000..4f09c0da278 --- /dev/null +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/environment/list/EnvironmentListAdapter.java @@ -0,0 +1,27 @@ +package de.symeda.sormas.app.environment.list; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import de.symeda.sormas.app.R; +import de.symeda.sormas.app.backend.environment.Environment; +import de.symeda.sormas.app.core.adapter.databinding.BindingPagedListAdapter; +import de.symeda.sormas.app.core.adapter.databinding.BindingViewHolder; +import de.symeda.sormas.app.databinding.RowEnvironmentListItemLayoutBinding; + +public class EnvironmentListAdapter extends BindingPagedListAdapter { + + public EnvironmentListAdapter() { + super(R.layout.row_environment_list_item_layout); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + super.onBindViewHolder(holder, position); + + if (getItemViewType(position) == TYPE_ITEM) { + BindingViewHolder pageHolder = (BindingViewHolder) holder; + pageHolder.setOnListItemClickListener(this.mOnListItemClickListener); + } + } +} diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/environment/list/EnvironmentListFragment.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/environment/list/EnvironmentListFragment.java new file mode 100644 index 00000000000..278968148c8 --- /dev/null +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/environment/list/EnvironmentListFragment.java @@ -0,0 +1,58 @@ +package de.symeda.sormas.app.environment.list; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import de.symeda.sormas.app.PagedBaseListFragment; +import de.symeda.sormas.app.R; +import de.symeda.sormas.app.backend.environment.Environment; +import de.symeda.sormas.app.core.adapter.databinding.OnListItemClickListener; + +public class EnvironmentListFragment extends PagedBaseListFragment implements OnListItemClickListener { + + private LinearLayoutManager linearLayoutManager; + + private RecyclerView recyclerViewForList; + + public static EnvironmentListFragment newInstance() { + return newInstance(EnvironmentListFragment.class, null, null); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = super.onCreateView(inflater, container, savedInstanceState); + linearLayoutManager = new LinearLayoutManager(getActivity(), RecyclerView.VERTICAL, false); + recyclerViewForList = view.findViewById(R.id.recyclerViewForList); + + return view; + } + + @Override + public EnvironmentListAdapter getNewListAdapter() { + return (EnvironmentListAdapter) ((EnvironmentListActivity) getActivity()).getAdapter(); + } + + @Override + public void onListItemClick(View view, int position, Object item) { + Environment environment = (Environment) item; + + } + + @Override + public void onResume() { + super.onResume(); + getSubHeadingHandler().updateSubHeadingTitle(); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + recyclerViewForList.setAdapter(getListAdapter()); + recyclerViewForList.setLayoutManager(linearLayoutManager); + } +} diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/environment/list/EnvironmentListViewModel.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/environment/list/EnvironmentListViewModel.java new file mode 100644 index 00000000000..fb78b39eb6a --- /dev/null +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/environment/list/EnvironmentListViewModel.java @@ -0,0 +1,108 @@ +package de.symeda.sormas.app.environment.list; + +import java.util.List; + +import androidx.annotation.NonNull; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; +import androidx.paging.DataSource; +import androidx.paging.LivePagedListBuilder; +import androidx.paging.PagedList; +import androidx.paging.PositionalDataSource; + +import de.symeda.sormas.app.backend.common.DatabaseHelper; +import de.symeda.sormas.app.backend.environment.Environment; +import de.symeda.sormas.app.backend.environment.EnvironmentCriteria; + +public class EnvironmentListViewModel extends ViewModel { + + private LiveData> environmentList; + + private EnvironmentFactory environmentFactory; + + public void initializeViewModel() { + initializeModel(new EnvironmentCriteria()); + } + + private void initializeModel(EnvironmentCriteria environmentCriteria) { + environmentFactory = new EnvironmentFactory(); + environmentFactory.setEnvironmentCriteria(environmentCriteria); + PagedList.Config config = new PagedList.Config.Builder().setEnablePlaceholders(true).setInitialLoadSizeHint(32).setPageSize(16).build(); + + LivePagedListBuilder environmentsListBuilder = new LivePagedListBuilder(environmentFactory, config); + environmentList = environmentsListBuilder.build(); + } + + public LiveData> getEnvironmentList() { + return environmentList; + } + + public EnvironmentCriteria getEnvironmentCriteria() { + return environmentFactory.getEnvironmentCriteria(); + } + + void notifyCriteriaUpdated() { + if (environmentList.getValue() != null) { + environmentList.getValue().getDataSource().invalidate(); + if (!environmentList.getValue().isEmpty()) { + environmentList.getValue().loadAround(0); + } + } + } + + public static class EnvironmentDataSource extends PositionalDataSource { + + private EnvironmentCriteria environmentCriteria; + + EnvironmentDataSource(EnvironmentCriteria environmentCriteria) { + this.environmentCriteria = environmentCriteria; + } + + @Override + public void loadInitial(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback callback) { + long totalCount = DatabaseHelper.getEnvironmentDao().countByCriteria(environmentCriteria); + int offset = params.requestedStartPosition; + int count = params.requestedLoadSize; + if (offset + count > totalCount) { + offset = (int) Math.max(0, totalCount - count); + } + List formDataList = DatabaseHelper.getEnvironmentDao().queryByCriteria(environmentCriteria, offset, count); + callback.onResult(formDataList, offset, (int) totalCount); + } + + @Override + public void loadRange(@NonNull LoadRangeParams params, @NonNull LoadRangeCallback callback) { + List environments = + DatabaseHelper.getEnvironmentDao().queryByCriteria(environmentCriteria, params.startPosition, params.loadSize); + callback.onResult(environments); + } + } + + public static class EnvironmentFactory extends DataSource.Factory { + + private MutableLiveData mutableDataSource; + private EnvironmentDataSource environmentDataSource; + private EnvironmentCriteria environmentCriteria; + + EnvironmentFactory() { + this.mutableDataSource = new MutableLiveData<>(); + } + + @NonNull + @Override + public DataSource create() { + environmentDataSource = new EnvironmentDataSource(environmentCriteria); + mutableDataSource.postValue(environmentDataSource); + return environmentDataSource; + } + + public EnvironmentCriteria getEnvironmentCriteria() { + return environmentCriteria; + } + + public void setEnvironmentCriteria(EnvironmentCriteria environmentCriteria) { + this.environmentCriteria = environmentCriteria; + } + } +} diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/EnvironmentFacadeRetro.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/EnvironmentFacadeRetro.java index 589bf33c055..24e9f3acc48 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/EnvironmentFacadeRetro.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/EnvironmentFacadeRetro.java @@ -4,7 +4,6 @@ import de.symeda.sormas.api.PostResponse; import de.symeda.sormas.api.environment.EnvironmentDto; -import de.symeda.sormas.api.report.AggregateReportDto; import retrofit2.Call; import retrofit2.http.Body; import retrofit2.http.GET; @@ -13,15 +12,18 @@ public interface EnvironmentFacadeRetro { - @GET("environments/all/{since}") - Call> pullAllSince(@Path("since") long since); + @GET("environments/all/{since}") + Call> pullAllSince(@Path("since") long since); - @POST("environments/query") - Call> pullByUuids(@Body List uuids); + @POST("environments/query") + Call> pullByUuids(@Body List uuids); - @POST("environments/push") - Call> pushAll(@Body List dtos); + @POST("environments/push") + Call> pushAll(@Body List dtos); - @GET("environments/uuids") - Call> pullUuids(); + @GET("environments/uuids") + Call> pullUuids(); + + @GET("environments/obsolete/{since}") + Call> pullObsoleteUuidsSince(@Path("since") long since); } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/SynchronizeDataAsync.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/SynchronizeDataAsync.java index 02a2f799b2f..3d2b2b7db3b 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/SynchronizeDataAsync.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/SynchronizeDataAsync.java @@ -38,6 +38,7 @@ import de.symeda.sormas.api.caze.CaseDataDto; import de.symeda.sormas.api.clinicalcourse.ClinicalVisitDto; import de.symeda.sormas.api.contact.ContactDto; +import de.symeda.sormas.api.environment.EnvironmentDto; import de.symeda.sormas.api.event.EventDto; import de.symeda.sormas.api.event.EventParticipantDto; import de.symeda.sormas.api.feature.FeatureType; @@ -73,6 +74,8 @@ import de.symeda.sormas.app.backend.contact.ContactDtoHelper; import de.symeda.sormas.app.backend.customizableenum.CustomizableEnumValueDtoHelper; import de.symeda.sormas.app.backend.disease.DiseaseConfigurationDtoHelper; +import de.symeda.sormas.app.backend.environment.Environment; +import de.symeda.sormas.app.backend.environment.EnvironmentDtoHelper; import de.symeda.sormas.app.backend.event.Event; import de.symeda.sormas.app.backend.event.EventDtoHelper; import de.symeda.sormas.app.backend.event.EventParticipantDtoHelper; @@ -144,7 +147,7 @@ protected Void doInBackground(Void... params) { try { boolean pullAndRemoveObsoleteNecessary = ConfigProvider.getLastObsoleteUuidsSyncDate() == null - || DateHelper.getFullDaysBetween(ConfigProvider.getLastObsoleteUuidsSyncDate(), new Date()) >= 1; + || DateHelper.getFullDaysBetween(ConfigProvider.getLastObsoleteUuidsSyncDate(), new Date()) >= 0; syncCallbacks .ifPresent(c -> c.getUpdateStepNumberCallback().accept(syncMode == SyncMode.Changes ? pullAndRemoveObsoleteNecessary ? 5 : 4 : 6)); syncCallbacks.ifPresent(c -> c.getShowDialogCallback().run()); @@ -335,6 +338,7 @@ private void synchronizeChangedData() throws DaoException, NoConnectionException EventDtoHelper eventDtoHelper = new EventDtoHelper(); EventParticipantDtoHelper eventParticipantDtoHelper = new EventParticipantDtoHelper(); SampleDtoHelper sampleDtoHelper = new SampleDtoHelper(); + EnvironmentDtoHelper environmentDtoHelper = new EnvironmentDtoHelper(); PathogenTestDtoHelper pathogenTestDtoHelper = new PathogenTestDtoHelper(); AdditionalTestDtoHelper additionalTestDtoHelper = new AdditionalTestDtoHelper(); ContactDtoHelper contactDtoHelper = new ContactDtoHelper(); @@ -360,6 +364,7 @@ private void synchronizeChangedData() throws DaoException, NoConnectionException boolean samplesNeedPull = sampleDtoHelper.pullAndPushEntities(context, syncCallbacks); boolean sampleTestsNeedPull = pathogenTestDtoHelper.pullAndPushEntities(context, syncCallbacks); boolean additionalTestsNeedPull = additionalTestDtoHelper.pullAndPushEntities(context, syncCallbacks); + boolean environmentsNeedPull = environmentDtoHelper.pullAndPushEntities(context, syncCallbacks); boolean contactsNeedPull = contactDtoHelper.pullAndPushEntities(context, syncCallbacks); boolean visitsNeedPull = visitDtoHelper.pullAndPushEntities(context, syncCallbacks); boolean tasksNeedPull = taskDtoHelper.pullAndPushEntities(context, syncCallbacks); @@ -380,6 +385,8 @@ private void synchronizeChangedData() throws DaoException, NoConnectionException DtoUserRightsHelper.isViewAllowed(PathogenTestDto.class) && DtoFeatureConfigHelper.isFeatureConfigForSampleTestsEnabled(); boolean additionalTestsVisible = DtoUserRightsHelper.isViewAllowed(AdditionalTestDto.class) && DtoFeatureConfigHelper.isFeatureConfigForAdditionalTestsEnabled(); + boolean environmentsVisible = + DtoUserRightsHelper.isViewAllowed(EnvironmentDto.class) && DtoFeatureConfigHelper.isFeatureConfigForEnvironmentEnabled(); boolean contactsVisible = DtoUserRightsHelper.isViewAllowed(ContactDto.class) && DtoFeatureConfigHelper.isFeatureConfigForContactsEnabled(); boolean visitsVisible = DtoUserRightsHelper.isViewAllowed(VisitDto.class) && DtoFeatureConfigHelper.isFeatureConfigForVisitsEnabled(); boolean tasksVisible = DtoUserRightsHelper.isViewAllowed(TaskDto.class) && DtoFeatureConfigHelper.isFeatureConfigForTasksEnabled(); @@ -437,6 +444,12 @@ private void synchronizeChangedData() throws DaoException, NoConnectionException pathogenTestDtoHelper.pullEntities(true, context, syncCallbacks, false); } } + if (environmentsVisible) { + syncCallbacks.ifPresent(c -> c.getLoadNextCallback().run()); + if (environmentsNeedPull) { + environmentDtoHelper.pullEntities(true, context, syncCallbacks, false); + } + } if (additionalTestsVisible) { syncCallbacks.ifPresent(c -> c.getLoadNextCallback().run()); if (additionalTestsNeedPull) { @@ -522,6 +535,7 @@ private void repullData() throws DaoException, NoConnectionException, ServerConn EventDtoHelper eventDtoHelper = new EventDtoHelper(); EventParticipantDtoHelper eventParticipantDtoHelper = new EventParticipantDtoHelper(); SampleDtoHelper sampleDtoHelper = new SampleDtoHelper(); + EnvironmentDtoHelper environmentDtoHelper = new EnvironmentDtoHelper(); PathogenTestDtoHelper pathogenTestDtoHelper = new PathogenTestDtoHelper(); AdditionalTestDtoHelper additionalTestDtoHelper = new AdditionalTestDtoHelper(); ContactDtoHelper contactDtoHelper = new ContactDtoHelper(); @@ -548,6 +562,7 @@ private void repullData() throws DaoException, NoConnectionException, ServerConn eventDtoHelper.repullEntities(context, syncCallbacks); eventParticipantDtoHelper.repullEntities(context, syncCallbacks); sampleDtoHelper.repullEntities(context, syncCallbacks); + environmentDtoHelper.repullEntities(context, syncCallbacks); pathogenTestDtoHelper.repullEntities(context, syncCallbacks); additionalTestDtoHelper.repullEntities(context, syncCallbacks); contactDtoHelper.repullEntities(context, syncCallbacks); @@ -717,6 +732,21 @@ private void pullAndRemoveObsoleteUuidsSince(Date since) throws NoConnectionExce } syncCallbacks.ifPresent(c -> c.getLoadNextCallback().run()); + if (DtoUserRightsHelper.isViewAllowed(Environment.class)) { + List environmentUuids = + executeUuidCall(RetroProvider.getEnvironmentFacade().pullObsoleteUuidsSince(since != null ? since.getTime() : 0)); + for (String environmentUuid : environmentUuids) { + DatabaseHelper.getEnvironmentDao().deleteEnvironmentAndAllDependingEntities(environmentUuid); + } + } + // Remove obsolete environments based on change date + List obsoleteEnvironments = DatabaseHelper.getEnvironmentDao().queryForObsolete(); + for (Environment obsoleteEnvironment : obsoleteEnvironments) { + DatabaseHelper.getEnvironmentDao().deleteEnvironmentAndAllDependingEntities(obsoleteEnvironment.getUuid()); + } + + syncCallbacks.ifPresent(c -> c.getLoadNextCallback().run()); + // Tasks if (DtoUserRightsHelper.isViewAllowed(TaskDto.class)) { List taskUuids = executeUuidCall(RetroProvider.getTaskFacade().pullObsoleteUuidsSince(since != null ? since.getTime() : 0)); @@ -815,6 +845,10 @@ private void pushNewPullMissingAndDeleteInvalidData() viewAllowed = DtoUserRightsHelper.isViewAllowed(SampleDto.class); List sampleUuids = viewAllowed ? executeUuidCall(RetroProvider.getSampleFacade().pullUuids()) : new ArrayList<>(); DatabaseHelper.getSampleDao().deleteInvalid(sampleUuids, syncCallbacks); + //environments + viewAllowed = DtoUserRightsHelper.isViewAllowed(Environment.class); + List environmentUuids = viewAllowed ? executeUuidCall(RetroProvider.getEnvironmentFacade().pullUuids()) : new ArrayList<>(); + DatabaseHelper.getEnvironmentDao().deleteInvalid(environmentUuids, syncCallbacks); // event participants viewAllowed = DtoUserRightsHelper.isViewAllowed(EventParticipantDto.class); List eventParticipantUuids = viewAllowed ? executeUuidCall(RetroProvider.getEventParticipantFacade().pullUuids()) : new ArrayList<>(); @@ -867,6 +901,7 @@ private void pushNewPullMissingAndDeleteInvalidData() new EventDtoHelper().pullMissing(eventUuids, syncCallbacks); new EventParticipantDtoHelper().pullMissing(eventParticipantUuids, syncCallbacks); new SampleDtoHelper().pullMissing(sampleUuids, syncCallbacks); + new EnvironmentDtoHelper().pullMissing(environmentUuids, syncCallbacks); new PathogenTestDtoHelper().pullMissing(sampleTestUuids, syncCallbacks); new AdditionalTestDtoHelper().pullMissing(additionalTestUuids, syncCallbacks); new ContactDtoHelper().pullMissing(contactUuids, syncCallbacks); diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/util/DateFormatHelper.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/util/DateFormatHelper.java index 94fbbfc567d..af97c2f45ea 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/util/DateFormatHelper.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/util/DateFormatHelper.java @@ -7,6 +7,7 @@ import de.symeda.sormas.api.person.ApproximateAgeType; import de.symeda.sormas.api.person.PersonHelper; import de.symeda.sormas.api.utils.DateHelper; +import de.symeda.sormas.app.backend.location.Location; public class DateFormatHelper { @@ -47,4 +48,12 @@ public static String formatDateInterval(Date startDate, Date endDate) { } return intervalDate; } + + public static String getLatLonLocation(Location location){ + if (location==null || location.getLatLonString().isEmpty()){ + return null; + }else { + return "GPS: " + location.getLatLonString(); + } + } } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/util/NavigationHelper.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/util/NavigationHelper.java index 7139fa32069..a7a6547d1d4 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/util/NavigationHelper.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/util/NavigationHelper.java @@ -28,6 +28,7 @@ import de.symeda.sormas.app.caze.list.CaseListActivity; import de.symeda.sormas.app.contact.list.ContactListActivity; import de.symeda.sormas.app.dashboard.DashboardActivity; +import de.symeda.sormas.app.environment.list.EnvironmentListActivity; import de.symeda.sormas.app.event.list.EventListActivity; import de.symeda.sormas.app.immunization.list.ImmunizationListActivity; import de.symeda.sormas.app.report.ReportActivity; @@ -73,6 +74,10 @@ public static void goToSamples(Context context) { SampleListActivity.startActivity(context, null); } + public static void goToEnvironments(Context context){ + EnvironmentListActivity.startActivity(context); + } + public static void goToImmunizations(Context context) { ImmunizationListActivity.startActivity(context); } diff --git a/sormas-app/app/src/main/res/drawable/ic_drawer_environment_blue_36dp.xml b/sormas-app/app/src/main/res/drawable/ic_drawer_environment_blue_36dp.xml new file mode 100644 index 00000000000..932f09d05ae --- /dev/null +++ b/sormas-app/app/src/main/res/drawable/ic_drawer_environment_blue_36dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/sormas-app/app/src/main/res/layout/filter_environment_list_layout.xml b/sormas-app/app/src/main/res/layout/filter_environment_list_layout.xml new file mode 100644 index 00000000000..a4ded153583 --- /dev/null +++ b/sormas-app/app/src/main/res/layout/filter_environment_list_layout.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sormas-app/app/src/main/res/layout/row_environment_list_item_layout.xml b/sormas-app/app/src/main/res/layout/row_environment_list_item_layout.xml new file mode 100644 index 00000000000..cb1da078710 --- /dev/null +++ b/sormas-app/app/src/main/res/layout/row_environment_list_item_layout.xml @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sormas-app/app/src/main/res/menu/drawer_main_menu.xml b/sormas-app/app/src/main/res/menu/drawer_main_menu.xml index d5827d15666..a07d658b89e 100644 --- a/sormas-app/app/src/main/res/menu/drawer_main_menu.xml +++ b/sormas-app/app/src/main/res/menu/drawer_main_menu.xml @@ -78,26 +78,34 @@ app:actionLayout="@layout/drawer_main_menu_notification_counter" /> + + diff --git a/sormas-app/app/src/main/res/values/strings.xml b/sormas-app/app/src/main/res/values/strings.xml index 2c507db470f..23621f7329c 100644 --- a/sormas-app/app/src/main/res/values/strings.xml +++ b/sormas-app/app/src/main/res/values/strings.xml @@ -391,6 +391,8 @@ Read Sample Sample Summary Sample Listing + Environment Listing + Edit Immunization New Immunization Read Immunization @@ -515,6 +517,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -673,6 +676,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/EnvironmentService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/EnvironmentService.java index c1fa8afa73f..9d803c48864 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/EnvironmentService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/EnvironmentService.java @@ -211,4 +211,16 @@ public Predicate buildCriteriaFilter(EnvironmentCriteria environmentCriteria, En public Predicate createDefaultFilter(CriteriaBuilder cb, From root) { return cb.isFalse(root.get(Environment.DELETED)); } + + @Override + @SuppressWarnings("rawtypes") + protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + + Predicate filter = createDefaultFilter(cb, from); + if (getCurrentUser() != null) { + filter = CriteriaBuilderHelper.and(cb, filter, createUserFilterInternal(cb, cq, from)); + } + + return filter; + } } diff --git a/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/EnvironmentResource.java b/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/EnvironmentResource.java index c1a1b0c1085..bdd02c1fac2 100644 --- a/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/EnvironmentResource.java +++ b/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/EnvironmentResource.java @@ -46,6 +46,12 @@ public EnvironmentDto getByUuid(@PathParam("uuid") String uuid) { return FacadeProvider.getEnvironmentFacade().getByUuid(uuid); } + @GET + @Path("/obsolete/{since}") + public List getObsoleteUuidsSince(@PathParam("since") long since) { + return FacadeProvider.getEnvironmentFacade().getObsoleteUuidsSince(new Date(since)); + } + @Override public UnaryOperator getSave() { return FacadeProvider.getEnvironmentFacade()::save; From 4ddc564959730d0fa051d6f85f2030f4f5b49cc4 Mon Sep 17 00:00:00 2001 From: Michal Kozakiewicz Date: Tue, 25 Jul 2023 15:15:41 +0200 Subject: [PATCH 113/174] SORQA-1046 Implementation "Re-send Case to Survnet" - added Test that check re-send case to Survnet --- .../pages/application/cases/EditCasePage.java | 3 ++ .../application/cases/CaseDirectorySteps.java | 26 ++++++------ .../web/application/cases/EditCaseSteps.java | 41 +++++++++++++++++++ .../features/sanity/web/Survnet.feature | 28 ++++++++++++- 4 files changed, 85 insertions(+), 13 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/EditCasePage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/EditCasePage.java index 8a31e04ad27..1597720a36a 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/EditCasePage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/EditCasePage.java @@ -394,6 +394,9 @@ public static By getByImmunizationUuid(String immunizationUuid) { public static final By ERROR_REVOKE_DESCRIPTION_REQUEST_PROCESSED = By.xpath( "//*[contains(text(),'Die Freigabeanfrage konnte nicht gefunden werden. Sie wurde entweder vom Quellsystem zur\u00FCckgezogen oder von jemand anderem abgelehnt. Bitte laden Sie die Seite neu, um die neuesten \u00C4nderungen zu sehen.')]"); + public static final By REPORTING_TOOLS_FOR_SURVNET_USER = + By.xpath( + "//div[contains(@location,'externalSurvToolGateway')]//div[contains(text(), 'Surv NETAUTO')]"); public static By getPreExistingConditionCombobox_DE(String id) { return By.xpath( diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDirectorySteps.java index 9382445e6ca..84a3bc205d1 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDirectorySteps.java @@ -120,18 +120,7 @@ import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.DATE_OF_REPORT_INPUT; import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.SAVE_BUTTON; import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.UUID_EXTERNAL_ID_EXTERNAL_TOKEN_LIKE_INPUT; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.ACTION_CLOSE; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.ACTION_CONFIRM; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.ARCHIVE_RELATED_CONTACTS_CHECKBOX; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.BACK_TO_CASES_BUTTON; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.CONFIRM_ACTION; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.CREATE_NEW_CASE_CHECKBOX; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.PICK_OR_CREATE_CASE_POPUP_HEADER; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.PICK_OR_CREATE_PERSON_POPUP_HEADER; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.REFERENCE_DEFINITION_TEXT; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.REPORTING_TOOL_MESSAGE; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.SAVE_POPUP_CONTENT; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.getCaseIDPathByIndex; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.*; import static org.sormas.e2etests.pages.application.cases.EditContactsPage.COMMIT_BUTTON; import static org.sormas.e2etests.pages.application.cases.EditContactsPage.FIRST_RESULT_IN_GRID_IMPORT_POPUP; import static org.sormas.e2etests.pages.application.cases.EditContactsPage.IMPORT_CASE_CONTACTS_BUTTON; @@ -1107,6 +1096,19 @@ public CaseDirectorySteps( webDriverHelpers.selectFromCombobox(CASE_DISPLAY_FILTER_COMBOBOX, caseParameter); TimeUnit.SECONDS.sleep(2); }); + + When( + "I validate the existence of {string} Reporting Tools entries in Survnet box", + (String number) -> { + int numberInt = Integer.parseInt(number); + TimeUnit.SECONDS.sleep(2); + softly.assertEquals( + webDriverHelpers.getNumberOfElements(REPORTING_TOOLS_FOR_SURVNET_USER), + numberInt, + "Number of sent entries to Survnet is not correct"); + softly.assertAll(); + }); + And( "I apply {string} to ownership combobox on Case Directory Page", (String caseParameter) -> { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java index b5a012fe072..fd45a1aa652 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java @@ -1826,6 +1826,24 @@ public EditCaseSteps( webDriverHelpers.waitForPageLoadingSpinnerToDisappear(40); }); + When( + "I check the end of processing date in the archive popup and select Archive contacts checkbox for DE", + () -> { + String endOfProcessingDate; + endOfProcessingDate = + webDriverHelpers.getValueFromWebElement(END_OF_PROCESSING_DATE_POPUP_INPUT); + + softly.assertEquals( + endOfProcessingDate, + LocalDate.now().format(DateTimeFormatter.ofPattern("d.MM.yyyy")), + "End of processing date is invalid"); + softly.assertAll(); + webDriverHelpers.clickOnWebElementBySelector(ARCHIVE_RELATED_CONTACTS_CHECKBOX); + webDriverHelpers.clickOnWebElementBySelector(EditContactPage.DELETE_POPUP_YES_BUTTON); + TimeUnit.SECONDS.sleep(3); // wait for response after confirm + webDriverHelpers.waitForPageLoadingSpinnerToDisappear(40); + }); + When( "I check the end of processing date in the archive popup and not select Archive contacts checkbox", () -> { @@ -2174,6 +2192,13 @@ public EditCaseSteps( webDriverHelpers.clickOnWebElementBySelector(DELETE_BUTTON); }); + When( + "I click on Restore button from case", + () -> { + webDriverHelpers.scrollToElement(DELETE_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(DELETE_BUTTON); + }); + When( "I check Delete button from case is enabled", () -> { @@ -2824,6 +2849,15 @@ public EditCaseSteps( webDriverHelpers.waitUntilIdentifiedElementIsPresent(REPORTING_TOOL_MESSAGE); }); + When( + "I check that Reporting tool in Survnet box contain {string} entry", + (String entry) -> { + softly.assertTrue( + webDriverHelpers.isElementPresent(checkTextInReportingToolComponent(entry)), + "Element is not present"); + softly.assertAll(); + }); + And( "^I collect case external UUID from Edit Case page$", () -> { @@ -3414,4 +3448,11 @@ private void selectQuarantineOrderTemplate(String templateName) { private void fillExtraComment(String extraComment) { webDriverHelpers.fillInAndLeaveWebElement(EditCasePage.EXTRA_COMMENT_TEXTAREA, extraComment); } + + public static By checkTextInReportingToolComponent(String text) { + return By.xpath( + String.format( + "//div[contains(@location,'externalSurvToolGateway')]//div[contains(text(), '%s')]", + text)); + } } diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature index 3652b1a189e..995aabb6733 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature @@ -346,4 +346,30 @@ Feature: Survnet tests Examples: | setting | | "Ambulant" | - | "Stationär" | \ No newline at end of file + | "Stationär" | + + @tmsLink=SORQA-1046 + Scenario: Re-send Case from SORMAS to Meldesoftware + Given I log in as a Survnet + When I click on the Cases button from navbar + And I click on the NEW CASE button + And I create a new case with mandatory data only for Survnet DE + Then I get the case person UUID displayed on Edit case page + And I click on Send to reporting tool button on Edit Case page + Then I check that Reporting tool in Survnet box contain "gesendet am" entry + And I delete the case for DE + And I apply "Gelöschte Fälle" to combobox on Case Directory Page + Then I click on the APPLY FILTERS button + And I click on the first Case ID from Case Directory + Then I check that Reporting tool in Survnet box contain "gelöscht am" entry + Then I click on Restore button from case + And I apply "Aktive Fälle" to combobox on Case Directory Page + And I click on the first Case ID from Case Directory + Then I get the case person UUID displayed on Edit case page + And I click on Send to reporting tool button on Edit Case page + Then I click on the Archive case button + Then I check the end of processing date in the archive popup and select Archive contacts checkbox for DE + And I click on save case button + And I click on De-Archive case button + And I fill De-Archive case popup with test automation reason + And I validate the existence of "5" Reporting Tools entries in Survnet box \ No newline at end of file From d79851a5af479bc6c3dc79ce7c8e8696787d41c6 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Tue, 25 Jul 2023 15:34:13 +0200 Subject: [PATCH 114/174] qu-auto/SORQA-980 Demis - Process a Lab message that has multiple pathogen test in a sample. New test steps have been added. --- ...bNotificationTemplateMultiplePathogen.json | 530 ++++++++++++++++++ .../services/api/demis/DemisApiService.java | 15 + .../steps/api/demisSteps/DemisSteps.java | 10 + .../features/sanity/web/DemisWeb.feature | 21 +- 4 files changed, 574 insertions(+), 2 deletions(-) create mode 100644 sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationTemplateMultiplePathogen.json diff --git a/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationTemplateMultiplePathogen.json b/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationTemplateMultiplePathogen.json new file mode 100644 index 00000000000..f5ef87f77e2 --- /dev/null +++ b/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationTemplateMultiplePathogen.json @@ -0,0 +1,530 @@ +{ + "resourceType": "Bundle", + "id": "NotificationBundleLaboratory-example", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotificationBundleLaboratory" + ] + }, + "identifier": { + "system": "https://demis.rki.de/fhir/NamingSystem/NotificationBundleId", + "value": "0de84a15-3f79-439a-a33c-a5989927cf7d" + }, + "type": "document", + "timestamp": "2020-10-05T07:37:44.979+02:00", + "entry": [ + { + "fullUrl": "https://demis.rki.de/fhir/Composition/a194b5c3-a3c5-4ceb-9087-d7fd87e1ec4e", + "resource": { + "resourceType": "Composition", + "id": "a194b5c3-a3c5-4ceb-9087-d7fd87e1ec4e", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotificationLaboratory" + ] + }, + "identifier": { + "system": "https://demis.rki.de/fhir/NamingSystem/NotificationId", + "value": "" + }, + "status": "final", + "type": { + "coding": [ + { + "system": "http://loinc.org", + "code": "34782-3", + "display": "Infectious disease Note" + } + ] + }, + "category": [ + { + "coding": [ + { + "system": "http://loinc.org", + "code": "11502-2", + "display": "Laboratory report" + } + ] + } + ], + "subject": { + "reference": "Patient/61ebe359-bfdc-4613-8bf2-c5e300945f0n17" + }, + "date": "2020-04-16", + "author": [ + { + "reference": "PractitionerRole/61ebe359-bfdc-4613-8bf2-c5e300945f0n18" + } + ], + "title": "SARS-CoV-2-Erregernachweismeldung", + "relatesTo": [ + { + "code": "appends", + "targetReference": { + "type": "Composition", + "identifier": { + "system": "https://demis.rki.de/fhir/NamingSystem/NotificationId", + "value": "" + } + } + } + ], + "section": [ + { + "code": { + "coding": [ + { + "system": "http://loinc.org", + "code": "11502-2", + "display": "Laboratory report" + } + ] + }, + "entry": [ + { + "reference": "DiagnosticReport/61ebe359-bfdc-4613-8bf2-c5e300945f0n19" + } + ] + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/PractitionerRole/61ebe359-bfdc-4613-8bf2-c5e300945f0n18", + "resource": { + "resourceType": "PractitionerRole", + "id": "61ebe359-bfdc-4613-8bf2-c5e300945f0n18", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotifierRole" + ] + }, + "organization": { + "reference": "Organization/98cda07d-1fa7-47f6-ad79-e66de48d6078" + } + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Patient/61ebe359-bfdc-4613-8bf2-c5e300945f0n17", + "resource": { + "resourceType": "Patient", + "id": "61ebe359-bfdc-4613-8bf2-c5e300945f0n17", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotifiedPerson" + ] + }, + "deceasedBoolean": "true", + "deceasedDateTime": "2021-07-29", + "name": [ + { + "use": "official", + "family": "", + "given": [ + "" + ] + } + ], + "telecom": [ + { + "extension": [ + { + "url": "https://demis.rki.de/fhir/StructureDefinition/Comment", + "valueString": "Ab 14 Uhr" + } + ], + "system": "phone", + "value": "+49 (0)12345 - 123456", + "use": "work" + } + ], + "gender": "male", + "birthDate": "1974-12-25", + "address": [ + { + "extension": [ + { + "url": "https://demis.rki.de/fhir/StructureDefinition/AddressUse", + "valueCoding": { + "system": "https://demis.rki.de/fhir/CodeSystem/addressUse", + "code": "ordinary" + } + }, + { + "url": "https://demis.rki.de/fhir/StructureDefinition/FacilityAddressNotifiedPerson", + "valueReference": { + "reference": "Organization/98cda07d-1fa7-47f6-ad79-e66de48d6078" + } + } + ], + "line": [ + "Teststrasse 123" + ], + "country": "DEU", + "city": "Berlin", + "postalCode": "" + } + ], + "contact": [ + { + "relationship": [ + { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v2-0131", + "code": "E" + } + ] + } + ], + "name": { + "use": "official", + "family": "Meier", + "given": [ + "Joachim" + ] + } + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/DiagnosticReport/61ebe359-bfdc-4613-8bf2-c5e300945f0n19", + "resource": { + "resourceType": "DiagnosticReport", + "id": "61ebe359-bfdc-4613-8bf2-c5e300945f0n19", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/LaboratoryReportCVDP" + ] + }, + "basedOn": [ + { + "type": "ServiceRequest", + "identifier": { + "system": "https://demis.rki.de/fhir/NamingSystem/ServiceRequestId", + "value": "2020-0003456" + } + } + ], + "status": "final", + "code": { + "coding": [ + { + "system": "https://demis.rki.de/fhir/CodeSystem/notificationCategory", + "code": "cvdp", + "display": "Severe-Acute-Respiratory-Syndrome-Coronavirus-2 (SARS-CoV-2)" + } + ] + }, + "subject": { + "reference": "Patient/61ebe359-bfdc-4613-8bf2-c5e300945f0n17" + }, + "issued": "2021-03-04T11:45:33+11:00", + "result": [ + { + "reference": "Observation/" + } + ], + "conclusionCode": [ + { + "coding": [ + { + "system": "https://demis.rki.de/fhir/CodeSystem/conclusionCode", + "code": "pathogenDetected" + } + ] + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Organization/98cda07d-1fa7-47f6-ad79-e66de48d6078", + "resource": { + "resourceType": "Organization", + "id": "98cda07d-1fa7-47f6-ad79-e66de48d6078", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotifierFacility" + ] + }, + "identifier": [ + { + "system": "https://fhir.kbv.de/NamingSystem/KBV_NS_Base_BSNR", + "value": "purpleHat_Id" + } + ], + "type": [ + { + "coding": [ + { + "system": "https://demis.rki.de/fhir/CodeSystem/organizationType", + "code": "laboratory" + } + ] + } + ], + "name": "PurpleHat", + "telecom": [ + { + "system": "phone", + "value": "+49 (0)12345 - 123456", + "use": "work" + } + ], + "address": [ + { + "line": [ + "Kurzer Weg 15" + ], + "city": "Teststadt", + "postalCode": "13055", + "country": "20422" + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Observation/", + "resource": { + "resourceType": "Observation", + "id": "", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/PathogenDetectionCVDP" + ] + }, + "identifier": { + "system": "https://demis.rki.de/fhir/NamingSystem/PathogenDetection", + "value": "externalID-1234" + }, + "status": "final", + "category": [ + { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/observation-category", + "code": "laboratory" + } + ] + } + ], + "code": { + "coding": [ + { + "system": "http://loinc.org", + "code": "95125-1", + "display": "SARS-CoV-2 (COVID-19) variant Sequencing Nom (Specimen)" + } + ] + }, + "subject": { + "reference": "Patient/61ebe359-bfdc-4613-8bf2-c5e300945f0n17" + }, + "valueString": "#B.1.1.7", + "interpretation": [ + { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation", + "code": "NEG" + } + ] + } + ], + "note": [ + { + "text": "Ich bin ein optionaler beschreibender Text ..." + } + ], + "method": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "115418004", + "display": "Viral Sequencing (procedure)" + } + ] + }, + "specimen": { + "reference": "Specimen/" + } + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Observation/", + "resource": { + "resourceType": "Observation", + "id": "", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/PathogenDetectionCVDP" + ] + }, + "identifier": { + "system": "https://demis.rki.de/fhir/NamingSystem/PathogenDetection", + "value": "externalID-0011" + }, + "status": "final", + "category": [ + { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/observation-category", + "code": "laboratory" + } + ] + } + ], + "code": { + "coding": [ + { + "system": "http://loinc.org", + "code": "96741-4", + "display": "SARS-CoV-2 (COVID-19) variant Sequencing Nom (Specimen)" + } + ] + }, + "subject": { + "reference": "Patient/61ebe359-bfdc-4613-8bf2-c5e300945f0n17" + }, + "valueString": "#P.1", + "interpretation": [ + { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation", + "code": "POS" + } + ] + } + ], + "note": [ + { + "text": "Ich bin ein optionaler beschreibender Text ..." + } + ], + "method": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "115418004", + "display": "Viral Sequencing (procedure)" + } + ] + }, + "specimen": { + "reference": "Specimen/" + } + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Specimen/", + "resource": { + "resourceType": "Specimen", + "id": "", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/SpecimenCVDP" + ] + }, + "type": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "309164002", + "display": "Upper respiratory swab sample (specimen)" + } + ] + }, + "subject": { + "reference": "Patient/61ebe359-bfdc-4613-8bf2-c5e300945f0n17" + }, + "receivedTime": "2020-09-27T22:01:38+02:00", + "collection": { + "collector": { + "reference": "PractitionerRole/xyz2f5-8384-4191-916b-10150c780453" + }, + "collectedDateTime": "2020-04-15T10:10:00Z" + }, + "processing": [ + { + "extension": [ + { + "url": "https://demis.rki.de/fhir/StructureDefinition/TransactionID", + "valueString": "IMS-DEMIS-10001-CVDP-be8131da-9024-41a4-a53c-3ce0d6f6fe37" + } + ], + "timeDateTime": "2020-08-18T08:10:00Z" + } + ], + "note": [ + { + "text": "Die Probe gehört zu einem Ausbruch." + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/PractitionerRole/xyz2f5-8384-4191-916b-10150c780453", + "resource": { + "resourceType": "PractitionerRole", + "id": "xyz2f5-8384-4191-916b-10150c780453", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/SubmittingRole" + ] + }, + "practitioner": { + "reference": "Practitioner/42cdf5-8384-4191-916b-10150c780453" + } + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Practitioner/42cdf5-8384-4191-916b-10150c780453", + "resource": { + "resourceType": "Practitioner", + "id": "42cdf5-8384-4191-916b-10150c780453", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/SubmittingPerson" + ] + }, + "name": [ + { + "use": "official", + "family": "Mantle", + "given": [ + "Karl-Heinz" + ] + } + ], + "telecom": [ + { + "system": "phone", + "value": "+49 (0)12345 - 123456", + "use": "work" + }, + { + "system": "phone", + "value": "+49 (0)12345 - 123567", + "use": "home" + } + ], + "address": [ + { + "use": "home", + "line": [ + "Erster Weg 1" + ], + "city": "Berlin", + "state": "DE-BE", + "postalCode": "10117", + "country": "20422" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java index bd9acd9ca2f..7bb929df2f2 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java @@ -272,6 +272,21 @@ public String prepareLabNotificationFileWithOneExistingFacility( return json; } + public String prepareLabNotificationFileWithMultiplePathogenOneSample( + String patientFirstName, String patientLastName) { + DemisData demisData = runningConfiguration.getDemisData(locale); + String file = "src/main/resources/demisJsonTemplates/labNotificationTemplateMultiplePathogen.json"; + String json = readFileAsString(file); + json = json.replace("", UUID.randomUUID().toString()); + json = json.replace("\"\"", "\"" + demisData.getPostalCode() + "\""); + json = json.replace("\"\"", "\"" + patientLastName + "\""); + json = json.replace("\"\"", "\"" + patientFirstName + "\""); + json = json.replace("", UUID.randomUUID().toString()); + json = json.replace("", UUID.randomUUID().toString()); + json = json.replace("", UUID.randomUUID().toString()); + return json; + } + /** Delete method once we start adding tests */ @SneakyThrows public String loginRequest() { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java index 57616effba6..4c2614aeef7 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java @@ -942,6 +942,16 @@ public DemisSteps( patientLastName = faker.name().lastName(); String json = demisApiService.prepareLabNotificationFileWithOneExistingFacility(patientFirstName, patientLastName); + Assert.assertTrue(demisApiService.sendLabRequest(json, loginToken), "Failed to send laboratory request"); + }); + + When( + "^I create and send Laboratory Notification with multiple pathogen in one sample$", + () -> { + patientFirstName = faker.name().firstName(); + patientLastName = faker.name().lastName(); + String json = demisApiService.prepareLabNotificationFileWithMultiplePathogenOneSample(patientFirstName, patientLastName); + Assert.assertTrue(demisApiService.sendLabRequest(json, loginToken), "Failed to send laboratory request"); }); } diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index 71a7aec701b..46bbd8ded44 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -570,8 +570,25 @@ Scenario: Create and send laboratory request via Demis @tmsLink=SORQA-980 @env_d2s @LoginKeycloak Scenario: Demis - Process a Lab message that has multiple pathogen test in a sample Given API : Login to DEMIS server - When I create and send Laboratory Notification with one existing facility + When I create and send Laboratory Notification with multiple pathogen in one sample And I log in as a Admin User And I click on the Messages button from navbar And I click on fetch messages button - And I filter by last created person via API in Messages Directory \ No newline at end of file + And I filter by last created person via API in Messages Directory + And I click on Verarbeiten button in Messages Directory + And I pick a new person in Pick or create person popup during case creation for DE + And I choose create new case in Pick or create entry form for DE + And I check that create new case form with pathogen detection reporting process is displayed for DE + And I fill only mandatory fields to convert laboratory message into a case for DE + And I click on save button in the case popup + Then I check that new sample form with pathogen detection reporting process is displayed + And I fill laboratory name with "Testing laboratory" in New Sample form while processing a DEMIS LabMessage + And I fill "first" pathogen laboratory name with "Testing laboratory pathogen 1" in New Sample form while processing a DEMIS LabMessage + And I fill "second" pathogen laboratory name with "Testing laboratory pathogen 2" in New Sample form while processing a DEMIS LabMessage + And I click on save sample button + And I click on save sample button + And I click on save sample button + And I click on YES button in Update case disease variant popup window + And I click on the Cases button from navbar + And I search the case by last created person via Demis message + Then I click on the first Case ID from Case Directory \ No newline at end of file From 4ddb1eac3518439844cd486c06d3981128ed45fd Mon Sep 17 00:00:00 2001 From: Michal Kozakiewicz Date: Tue, 25 Jul 2023 15:39:36 +0200 Subject: [PATCH 115/174] SORQA-1046 Implementation "Re-send Case to Survnet" - implement missing step --- .../pages/application/samples/EditSamplePage.java | 7 ++++++- .../steps/web/application/cases/EditCaseSteps.java | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/samples/EditSamplePage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/samples/EditSamplePage.java index dabd5c0aa14..4a380720647 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/samples/EditSamplePage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/samples/EditSamplePage.java @@ -73,6 +73,9 @@ public class EditSamplePage { public static final By DELETE_SAMPLE_REASON_POPUP = By.xpath( "//div[@class='popupContent']//*[text()='Reason for deletion']/../following-sibling::div//div"); + public static final By DELETE_SAMPLE_REASON_POPUP_FOR_DE = + By.xpath( + "//div[@class='popupContent']//*[text()='Grund des L\u00F6schens']/../following-sibling::div//div"); public static final By EDIT_PATHOGEN_TEST = By.cssSelector(".v-align-right.v-slot.v-slot-compact.v-slot-link > div[role='button']"); public static final By TESTED_DISEASE_VARIANT = @@ -81,5 +84,7 @@ public class EditSamplePage { By.cssSelector("[class='popupContent'] [id='pcrTestSpecification'] input"); public static final By SEE_SAMPLES_FOR_THIS_PERSON_BUTTON_DE = By.id("Proben f\u00FCr diese Person ansehen"); - public static final By BACK_TO_CASE_DE_BUTTON = By.xpath("//div[@class='v-link v-widget v-caption v-link-v-caption']//span[contains(text(), 'Fall')]"); + public static final By BACK_TO_CASE_DE_BUTTON = + By.xpath( + "//div[@class='v-link v-widget v-caption v-link-v-caption']//span[contains(text(), 'Fall')]"); } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java index fd45a1aa652..c0e4cd24d83 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java @@ -289,6 +289,7 @@ import static org.sormas.e2etests.pages.application.persons.EditPersonPage.EVENT_PARTICIPANTS_DATA_TAB; import static org.sormas.e2etests.pages.application.samples.CreateNewSamplePage.SAMPLE_TYPE_COMBOBOX; import static org.sormas.e2etests.pages.application.samples.EditSamplePage.DELETE_SAMPLE_REASON_POPUP; +import static org.sormas.e2etests.pages.application.samples.EditSamplePage.DELETE_SAMPLE_REASON_POPUP_FOR_DE; import static org.sormas.e2etests.steps.BaseSteps.locale; import static org.sormas.e2etests.steps.web.application.contacts.ContactDirectorySteps.exposureData; @@ -1669,6 +1670,19 @@ public EditCaseSteps( webDriverHelpers.waitUntilElementIsVisibleAndClickable(CASE_APPLY_FILTERS_BUTTON); }); + When( + "I delete the case for DE", + () -> { + webDriverHelpers.waitUntilIdentifiedElementIsVisibleAndClickable(UUID_INPUT); + webDriverHelpers.scrollToElement(DELETE_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(DELETE_BUTTON); + webDriverHelpers.selectFromCombobox( + DELETE_SAMPLE_REASON_POPUP_FOR_DE, + "L\u00F6schen auf Anforderung der betroffenen Person nach DSGVO"); + webDriverHelpers.clickOnWebElementBySelector(DELETE_POPUP_YES_BUTTON); + webDriverHelpers.waitUntilElementIsVisibleAndClickable(CASE_APPLY_FILTERS_BUTTON); + }); + When( "I navigate to epidemiological data tab in Edit case page", () -> { From 3e3dcdab1456c173e370e2fab5cdcdc5041c4f2c Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Tue, 25 Jul 2023 15:56:43 +0200 Subject: [PATCH 116/174] qu-auto/SORQA-980 Demis - Process a Lab message that has multiple pathogen test in a sample. Json tamplate file has been changed. --- .../labNotificationTemplateMultiplePathogen.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationTemplateMultiplePathogen.json b/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationTemplateMultiplePathogen.json index f5ef87f77e2..b429cb24a65 100644 --- a/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationTemplateMultiplePathogen.json +++ b/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationTemplateMultiplePathogen.json @@ -279,7 +279,7 @@ "Kurzer Weg 15" ], "city": "Teststadt", - "postalCode": "13055", + "postalCode": "", "country": "20422" } ] From 8fff4c4ebfc9f95abd9d9f120570741b6757dea0 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Tue, 25 Jul 2023 16:44:04 +0200 Subject: [PATCH 117/174] qu-auto/SORQA-980 Demis - Process a Lab message that has multiple pathogen test in a sample. New test steps have been added. --- .../messages/MessagesDirectoryPage.java | 4 ++++ .../services/api/demis/DemisApiService.java | 2 +- .../steps/api/demisSteps/DemisSteps.java | 24 +++++++++++++++++++ .../features/sanity/web/DemisWeb.feature | 17 +++++++++++-- 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java index b3f159eb3ce..3da9cb5842b 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java @@ -140,4 +140,8 @@ public static By getProcessStatusByIndex(int index) { By.xpath("(//input[contains(@id, 'labDetails')])[3]"); public static final By MULTIPLE_SAMPLES_HEADER = By.xpath("//div[@class= 'v-window-header'][text()='Mehrere Proben']"); public static final By CREATE_NEW_SAMPLE_CHECKBOX = By.xpath("//span[@class= 'v-radiobutton v-select-option']//label[text()='Neue Probe erstellen']"); + public static final By NEW_SAMPLE_FORM_FIRST_PATHOGEN_TEST_TYPE_INPUT = + By.xpath("(//div[contains(@id, 'testType')]//input)[1]"); + public static final By NEW_SAMPLE_FORM_SECOND_PATHOGEN_TEST_TYPE_INPUT = + By.xpath("(//div[contains(@id, 'testType')]//input)[2]"); } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java index 7bb929df2f2..5399568087c 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java @@ -281,7 +281,7 @@ public String prepareLabNotificationFileWithMultiplePathogenOneSample( json = json.replace("\"\"", "\"" + demisData.getPostalCode() + "\""); json = json.replace("\"\"", "\"" + patientLastName + "\""); json = json.replace("\"\"", "\"" + patientFirstName + "\""); - json = json.replace("", UUID.randomUUID().toString()); + json = json.replace("", specimenUUID); json = json.replace("", UUID.randomUUID().toString()); json = json.replace("", UUID.randomUUID().toString()); return json; diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java index 4c2614aeef7..6b4e7ca7ffe 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java @@ -80,9 +80,11 @@ import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_CASE_FORM_DISEASE_VARIANT_INPUT; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_FIRST_PATHOGEN_DISEASE_VARIANT_INPUT; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_FIRST_PATHOGEN_LABORATORY_NAME; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_FIRST_PATHOGEN_TEST_TYPE_INPUT; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_LABORATORY_NAME; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_SECOND_PATHOGEN_DISEASE_VARIANT_INPUT; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_SECOND_PATHOGEN_LABORATORY_NAME; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_SECOND_PATHOGEN_TEST_TYPE_INPUT; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.PATIENT_BIRTHDAY_FROM_INPUT; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.PATIENT_BIRTHDAY_TO_INPUT; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.POPUP_CONFIRM_BUTTON; @@ -954,6 +956,28 @@ public DemisSteps( Assert.assertTrue(demisApiService.sendLabRequest(json, loginToken), "Failed to send laboratory request"); }); + + And( + "^I verify that test type for \"([^\"]*)\" pathogen is prefilled with \"([^\"]*)\" in New Sample form while processing a DEMIS LabMessage$", + (String pathogen, String testType) -> { + webDriverHelpers.waitUntilIdentifiedElementIsPresent(NEW_SAMPLE_FORM_FIRST_PATHOGEN_TEST_TYPE_INPUT); + switch (pathogen) { + case "first": + softly.assertEquals( + webDriverHelpers.getValueFromWebElement(NEW_SAMPLE_FORM_FIRST_PATHOGEN_TEST_TYPE_INPUT), + testType, + "The disease variant is incorrect"); + softly.assertAll(); + break; + case "second": + softly.assertEquals( + webDriverHelpers.getValueFromWebElement(NEW_SAMPLE_FORM_SECOND_PATHOGEN_TEST_TYPE_INPUT), + testType, + "The disease variant is incorrect"); + softly.assertAll(); + break; + } + }); } private List> getTableRowsData() { diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index 46bbd8ded44..7f82efdf6de 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -583,12 +583,25 @@ Scenario: Create and send laboratory request via Demis And I click on save button in the case popup Then I check that new sample form with pathogen detection reporting process is displayed And I fill laboratory name with "Testing laboratory" in New Sample form while processing a DEMIS LabMessage + And I verify that test type for "first" pathogen is prefilled with "Nukleinsäure-Nachweis (z.B. PCR)" in New Sample form while processing a DEMIS LabMessage + And I verify that test type for "second" pathogen is prefilled with "Gesamtgenomsequenzierung" in New Sample form while processing a DEMIS LabMessage And I fill "first" pathogen laboratory name with "Testing laboratory pathogen 1" in New Sample form while processing a DEMIS LabMessage And I fill "second" pathogen laboratory name with "Testing laboratory pathogen 2" in New Sample form while processing a DEMIS LabMessage And I click on save sample button And I click on save sample button And I click on save sample button - And I click on YES button in Update case disease variant popup window And I click on the Cases button from navbar And I search the case by last created person via Demis message - Then I click on the first Case ID from Case Directory \ No newline at end of file + Then I click on the first Case ID from Case Directory + And I click on edit sample icon of the 1 displayed sample on Edit Case page + And I check that lab sample id match "first" specimen id from Demis message on Edit Sample page + And I validate the existence of "2" pathogen tests + And I back to the case from Edit Sample page DE + And I check if report side component in Edit Case has today date + When I click on edit Report on Edit Case page + And I click on discard button + And I click on Display associated external messages button from Reports side component + And I check if external message window appears and close it + Then I click on the Messages button from navbar + And I filter by last created person via API in Messages Directory + And I verify that status for result 1 is set to processed in Message Directory page \ No newline at end of file From e9cc87f5fb9567202215efa2eb5eb1cb08459d8b Mon Sep 17 00:00:00 2001 From: Martin Wahnschaffe Date: Tue, 6 Jun 2023 16:59:53 +0200 Subject: [PATCH 118/174] #12045 use docker container for local keycloak postgres database replaced parameterized docker command with docker compose file --- .gitignore | 1 + sormas-base/setup/keycloak/.env | 23 ++++ sormas-base/setup/keycloak/docker-compose.yml | 62 +++++++++ sormas-base/setup/keycloak/keycloak-setup.sh | 120 ++++++------------ 4 files changed, 123 insertions(+), 83 deletions(-) create mode 100644 sormas-base/setup/keycloak/.env create mode 100644 sormas-base/setup/keycloak/docker-compose.yml diff --git a/.gitignore b/.gitignore index d076a5c3197..37086e31701 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ deploy /sormas-app/java_pid21052.hprof bin /sormas-base/setup/setup.log +/sormas-base/setup/keycloak/keycloak_setup.log # Exclude maven wrapper !/.mvn/wrapper/maven-wrapper.jar diff --git a/sormas-base/setup/keycloak/.env b/sormas-base/setup/keycloak/.env new file mode 100644 index 00000000000..a9d9ed9d5f0 --- /dev/null +++ b/sormas-base/setup/keycloak/.env @@ -0,0 +1,23 @@ +SORMAS_DOCKER_VERSION=latest +SORMAS_SERVER_URL=localhost:6080 + +KEYCLOAK_PORT=7080 +KEYCLOAK_HOST=localhost:${KEYCLOAK_PORT} +KEYCLOAK_DB_HOST=keycloak-postgres +KEYCLOAK_DB_NAME=keycloak +KEYCLOAK_DB_USER=keycloak +KEYCLOAK_DB_PASSWORD=password +KEYCLOAK_ADMIN_USER=admin +KEYCLOAK_ADMIN_PASSWORD=password + +KEYCLOAK_SORMAS_UI_SECRET=changeit +KEYCLOAK_SORMAS_REST_SECRET=changeit +KEYCLOAK_SORMAS_BACKEND_SECRET=changeit + +KEYCLOAK_CPUS=2.0 +KEYCLOAK_MEM=1024M +KEYCLOAK_MEM_RESERVED=512M + +KEYCLOAK_DB_MEM=2000M +KEYCLOAK_DB_MEM_RESERVED=1000M +KEYCLOAK_DB_CPUS=2.0 \ No newline at end of file diff --git a/sormas-base/setup/keycloak/docker-compose.yml b/sormas-base/setup/keycloak/docker-compose.yml new file mode 100644 index 00000000000..765bd68c049 --- /dev/null +++ b/sormas-base/setup/keycloak/docker-compose.yml @@ -0,0 +1,62 @@ +version: '2.3' + +services: + keycloak: + links: + - keycloak-postgres + depends_on: + keycloak-postgres: + condition: service_healthy + restart: unless-stopped + labels: + - autoheal=true + image: hzibraunschweig/sormas-keycloak:${SORMAS_DOCKER_VERSION} + ports: + - ${KEYCLOAK_PORT}:8080 + environment: + - KC_HOSTNAME=${KEYCLOAK_HOST} + - KEYCLOAK_ADMIN=${KEYCLOAK_ADMIN_USER} + - KEYCLOAK_ADMIN_PASSWORD=${KEYCLOAK_ADMIN_PASSWORD} + - KC_DB_URL_HOST=${KEYCLOAK_DB_HOST} + - KC_DB_USERNAME=${KEYCLOAK_DB_USER} + - KC_DB_PASSWORD=${KEYCLOAK_DB_PASSWORD} + - PROXY_ADDRESS_FORWARDING=true + - SORMAS_HOST_URL=${SORMAS_HOST} + - KEYCLOAK_SORMAS_UI_SECRET=${KEYCLOAK_SORMAS_UI_SECRET} + - KEYCLOAK_SORMAS_REST_SECRET=${KEYCLOAK_SORMAS_REST_SECRET} + - KEYCLOAK_SORMAS_BACKEND_SECRET=${KEYCLOAK_SORMAS_BACKEND_SECRET} + cpus: ${KEYCLOAK_CPUS} + mem_limit: ${KEYCLOAK_MEM} + mem_reservation: ${KEYCLOAK_MEM_RESERVED} + healthcheck: + test: ["CMD", "/opt/keycloak/bin/kcadm.sh", "config", "credentials", "--server", "http://localhost:8080/keycloak", "--realm", "master", "--user", "${KEYCLOAK_ADMIN_USER}", "--password", "${KEYCLOAK_ADMIN_PASSWORD}"] + interval: 30s + timeout: 3s + retries: 3 + start_period: 300s + + keycloak-postgres: + volumes: + - ${SORMAS_PATH}/keycloak/psqldata:/var/lib/postgresql/data + ports: + - 5433:5432 + expose: + - 5432 + restart: unless-stopped + labels: + - autoheal=true + command: -c 'config_file=/etc/postgresql/postgresql.conf' + image: hzibraunschweig/keycloak-postgres:${SORMAS_DOCKER_VERSION} + environment: + - POSTGRES_PASSWORD=${KEYCLOAK_DB_PASSWORD} + - POSTGRES_USER=${KEYCLOAK_DB_USER} + - POSTGRES_DB=${KEYCLOAK_DB_NAME} + cpus: ${KEYCLOAK_DB_CPUS} + mem_limit: ${KEYCLOAK_DB_MEM} + mem_reservation: ${KEYCLOAK_DB_MEM_RESERVED} + healthcheck: + test: [ "CMD", "psql", "-U", "${KEYCLOAK_DB_USER}", "-c", "SELECT 1;", "${KEYCLOAK_DB_NAME}" ] + interval: 30s + timeout: 3s + retries: 3 + start_period: 30s diff --git a/sormas-base/setup/keycloak/keycloak-setup.sh b/sormas-base/setup/keycloak/keycloak-setup.sh index 75f5e40ab7f..4efde00e6f4 100644 --- a/sormas-base/setup/keycloak/keycloak-setup.sh +++ b/sormas-base/setup/keycloak/keycloak-setup.sh @@ -17,8 +17,6 @@ # along with this program. If not, see . #******************************************************************************* - - rm -f keycloak_setup.log exec > >(tee -ia keycloak_setup.log) exec 2> >(tee -ia keycloak_setup.log) @@ -41,6 +39,7 @@ else ROOT_PREFIX=/c fi + if [ -x "$(command -v docker)" ]; then echo "Found docker" else @@ -50,11 +49,8 @@ fi echo "# Checking if the Payara server is up and running" -# Update this variables to match your payara installation +# Update these variables to match your payara installation # If the script is ran from the master server-setup.sh script, the variables will be filled automatically -if [[ -z "$DB_PORT" ]]; then - DB_PORT=5432 -fi if [[ -z "$PORT_BASE" ]]; then PORT_BASE=6080 echo "Using default Payara PORT_BASE ${PORT_BASE}" @@ -88,9 +84,7 @@ if [[ ! -d ${PAYARA_HOME} ]];then fi ${PAYARA_HOME}/bin/asadmin restart-domain --domaindir ${DOMAINS_HOME} ${DOMAIN_NAME} - PAYARA_STATUS=$? - if [[ 0 != $PAYARA_STATUS ]]; then echo "ERROR: Cannot start payara. Status ${PAYARA_STATUS}" exit 2 @@ -99,98 +93,58 @@ fi ASADMIN="${PAYARA_HOME}/bin/asadmin --port ${PORT_ADMIN}" # Keycloak settings -KEYCLOAK_PORT=7080 -if [[ -z "$KEYCLOAK_HOSTNAME" ]]; then - KEYCLOAK_HOSTNAME="localhost:${KEYCLOAK_PORT}" - echo "Using default KEYCLOAK_HOSTNAME ${KEYCLOAK_HOSTNAME}" +if [[ -z "$KEYCLOAK_PORT" ]]; then + export $(grep KEYCLOAK_PORT= < .env) +fi +echo "KEYCLOAK_PORT: ${KEYCLOAK_PORT}" +if [[ -z "$KEYCLOAK_SORMAS_UI_SECRET" ]]; then + export $(grep KEYCLOAK_SORMAS_UI_SECRET= < .env) +fi +if [[ -z "$KEYCLOAK_SORMAS_REST_SECRET" ]]; then + export $(grep KEYCLOAK_SORMAS_REST_SECRET= < .env) +fi +if [[ -z "$KEYCLOAK_SORMAS_BACKEND_SECRET" ]]; then + export $(grep KEYCLOAK_SORMAS_BACKEND_SECRET= < .env) fi -DB_HOST=localhost - -KEYCLOAK_DB_HOST=host.docker.internal -KEYCLOAK_DB_PORT=5432 -KEYCLOAK_DB_NAME=keycloak -KEYCLOAK_DB_USER=keycloak -KEYCLOAK_DB_VENDOR=postgres -KEYCLOAK_ADMIN_USER=admin -KEYCLOAK_ADMIN_PASSWORD=password - -KEYCLOAK_SORMAS_UI_SECRET=changeit -KEYCLOAK_SORMAS_REST_SECRET=changeit -KEYCLOAK_SORMAS_BACKEND_SECRET=changeit - -echo "Keycloak port: ${KEYCLOAK_PORT}" - -echo "Preparing the local Keycloak DB" - -while [[ -z "${KEYCLOAK_DB_PASSWORD}" ]]; do - read -r -p "--- Enter a password for the new database user '${KEYCLOAK_DB_USER}': " KEYCLOAK_DB_PASSWORD -done - -cat > setup.sql <<-EOF -CREATE USER ${KEYCLOAK_DB_USER} WITH PASSWORD '${KEYCLOAK_DB_PASSWORD}' CREATEDB; -CREATE DATABASE ${KEYCLOAK_DB_NAME} WITH OWNER = '${KEYCLOAK_DB_USER}' ENCODING = 'UTF8'; -EOF +if [[ -z "$KEYCLOAK_HOST" ]]; then + export KEYCLOAK_HOST="localhost:${KEYCLOAK_PORT}" +fi +echo "KEYCLOAK_HOST: ${KEYCLOAK_HOST}" -if [[ ${LINUX} = true ]]; then - # no host is specified as by default the postgres user has only local access - su postgres -c "psql -p ${DB_PORT} < setup.sql" +if [[ -z "$DEV_SYSTEM" ]]; then + DEV_SYSTEM=true +fi +if [[ ${DEV_SYSTEM} = true ]]; then + KEYCLOAK_URL="http://${KEYCLOAK_HOST}" else - if [[ -z ${PSQL} ]]; then - PSQL_DEFAULT="${PROGRAMFILES//\\/\/}/PostgreSQL/10/" - echo "--- Enter the name install path of Postgres on your system (default: ${PSQL_DEFAULT}:" - read -r PSQL_DIR - if [[ -z "${PSQL_DIR}" ]]; then - PSQL_DIR="${PSQL_DEFAULT}" - fi - PSQL="${PSQL_DIR}/bin/psql.exe" - fi - if [[ -z ${DB_PG_PW} ]]; then - while [[ -z "${DB_PG_PW}" ]]; do - read -r -p "--- Enter the password for the 'postgres' user of your database: " DB_PG_PW - done - fi - "${PSQL}" --no-password --file=setup.sql "postgresql://postgres:${DB_PG_PW}@${DB_HOST}:${DB_PORT}/postgres" + KEYCLOAK_URL="https://${KEYCLOAK_HOST}" fi read -p "--- Press [Enter] to continue..." -echo "Running Keycloak as a docker image" - -KEYCLOAK_DOCKER_CMD="-e KEYCLOAK_ADMIN=${KEYCLOAK_ADMIN_USER} " -KEYCLOAK_DOCKER_CMD+="-e KEYCLOAK_ADMIN_PASSWORD=${KEYCLOAK_ADMIN_PASSWORD} " -KEYCLOAK_DOCKER_CMD+="-e KC_DB_URL_HOST=${KEYCLOAK_DB_HOST} " -KEYCLOAK_DOCKER_CMD+="-e KC_DB_PORT=${KEYCLOAK_DB_PORT} " -KEYCLOAK_DOCKER_CMD+="-e KC_DB_USERNAME=${KEYCLOAK_DB_USER} " -KEYCLOAK_DOCKER_CMD+="-e KC_DB_PASSWORD=${KEYCLOAK_DB_PASSWORD} " -KEYCLOAK_DOCKER_CMD+="-e PROXY_ADDRESS_FORWARDING=true " -KEYCLOAK_DOCKER_CMD+="-e KC_HOSTNAME=${KEYCLOAK_HOSTNAME} " -KEYCLOAK_DOCKER_CMD+="-e SORMAS_SERVER_URL=${SORMAS_SERVER_URL} " -KEYCLOAK_DOCKER_CMD+="-e KEYCLOAK_SORMAS_UI_SECRET=${KEYCLOAK_SORMAS_UI_SECRET} " -KEYCLOAK_DOCKER_CMD+="-e KEYCLOAK_SORMAS_REST_SECRET=${KEYCLOAK_SORMAS_REST_SECRET} " -KEYCLOAK_DOCKER_CMD+="-e KEYCLOAK_SORMAS_BACKEND_SECRET=${KEYCLOAK_SORMAS_BACKEND_SECRET} " -KEYCLOAK_DOCKER_CMD+="-p ${KEYCLOAK_PORT}:8080 " - -KEYCLOAK_DOCKER_CMD+="hzibraunschweig/sormas-keycloak:latest" - -docker run -d --name sormas_keycloak ${KEYCLOAK_DOCKER_CMD} +echo "Running Keycloak and keycloak database docker containers" + +docker compose up --detach + echo "Updating Payara with Keycloak configurations" ${ASADMIN} set-config-property --propertyName=payara.security.openid.clientId --propertyValue=sormas-ui --source=domain ${ASADMIN} set-config-property --propertyName=payara.security.openid.clientSecret --propertyValue=${KEYCLOAK_SORMAS_UI_SECRET} --source=domain ${ASADMIN} set-config-property --propertyName=payara.security.openid.scope --propertyValue=openid --source=domain -${ASADMIN} set-config-property --propertyName=payara.security.openid.providerURI --propertyValue=http://localhost:${KEYCLOAK_PORT}/keycloak/realms/SORMAS --source=domain +${ASADMIN} set-config-property --propertyName=payara.security.openid.providerURI --propertyValue=${KEYCLOAK_URL}/keycloak/realms/SORMAS --source=domain ${ASADMIN} set-config-property --propertyName=payara.security.openid.provider.notify.logout --propertyValue=true --source=domain ${ASADMIN} set-config-property --propertyName=payara.security.openid.logout.redirectURI --propertyValue=http://${SORMAS_SERVER_URL}/sormas-ui -${ASADMIN} set-config-property --propertyName=sormas.rest.security.oidc.json --propertyValue="{\"realm\":\"SORMAS\",\"auth-server-url\":\"http://localhost:${KEYCLOAK_PORT}/keycloak\",\"ssl-required\":\"external\",\"resource\":\"sormas-rest\",\"credentials\":{\"secret\":\"${KEYCLOAK_SORMAS_REST_SECRET}\"},\"confidential-port\":0,\"principal-attribute\":\"preferred_username\",\"enable-basic-auth\":true}" --source=domain -${ASADMIN} set-config-property --propertyName=sormas.backend.security.oidc.json --propertyValue="{\"realm\":\"SORMAS\",\"auth-server-url\":\"http://localhost:${KEYCLOAK_PORT}/keycloak\",\"ssl-required\":\"external\",\"resource\":\"sormas-backend\",\"credentials\":{\"secret\":\"${KEYCLOAK_SORMAS_BACKEND_SECRET}\"},\"confidential-port\":0}" --source=domain +${ASADMIN} set-config-property --propertyName=sormas.rest.security.oidc.json --propertyValue="{\"realm\":\"SORMAS\",\"auth-server-url\":\"${KEYCLOAK_URL}/keycloak\",\"ssl-required\":\"external\",\"resource\":\"sormas-rest\",\"credentials\":{\"secret\":\"${KEYCLOAK_SORMAS_REST_SECRET}\"},\"confidential-port\":0,\"principal-attribute\":\"preferred_username\",\"enable-basic-auth\":true}" --source=domain +${ASADMIN} set-config-property --propertyName=sormas.backend.security.oidc.json --propertyValue="{\"realm\":\"SORMAS\",\"auth-server-url\":\"${KEYCLOAK_URL}/keycloak\",\"ssl-required\":\"external\",\"resource\":\"sormas-backend\",\"credentials\":{\"secret\":\"${KEYCLOAK_SORMAS_BACKEND_SECRET}\"},\"confidential-port\":0}" --source=domain echo "Setup is done and Keycloak is starting up (in case of any error you can go again trough the keycloak_setup.sh script)" -echo "You can start Keycloak by using the following command" -echo " docker run ${KEYCLOAK_DOCKER_CMD}" +echo "You can start the Keycloak container pair by using the following command:" +echo " docker start keycloak-keycloak-postgres-1 keycloak-keycloak-1" +echo "Or from within the current directory:" +echo " docker compose up" echo "Please make sure to perform the following steps:" -echo " - Update email settings in Keycloak Admin http://localhost:${KEYCLOAK_PORT}/keycloak" -echo " - Make sure the clients rootUrl are setup correctly" -echo " - Create an admin user in Keycloak which can be used to Sync other users" +echo " - Update email settings in Keycloak Admin ${KEYCLOAK_URL}/keycloak" +echo " - Make sure the clients rootUrl are setup correctly - on dev systems https will have to be replaced by http" echo " - In order to user Keycloak with Payara set 'authentication.provider=KEYCLOAK' property in sormas.properties" read -p "--- Press [Enter] to continue..." From f84cd92076729c55f6acf2ac884777f71aee6799 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Wed, 26 Jul 2023 09:42:43 +0200 Subject: [PATCH 119/174] qu-auto/SORQA-1049 Stabilize "Demis - Process a Lab message that has multiple samples". Report side component date checking method has been changed. --- .../messages/MessagesDirectorySteps.java | 43 ++++++++++++------- .../features/sanity/web/DemisWeb.feature | 2 +- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java index b64d076a611..377a259aeee 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java @@ -1,5 +1,23 @@ package org.sormas.e2etests.steps.web.application.messages; +import cucumber.api.java8.En; +import lombok.extern.slf4j.Slf4j; +import org.openqa.selenium.Keys; +import org.openqa.selenium.interactions.Actions; +import org.sormas.e2etests.helpers.AssertHelpers; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.steps.BaseSteps; +import org.testng.Assert; +import org.testng.asserts.SoftAssert; + +import javax.inject.Inject; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.checkTextInReportSideComponent; import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.ACTION_CONFIRM_POPUP_BUTTON; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.ACTION_YES_BUTTON; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CLOSE_POPUP; @@ -40,22 +58,6 @@ import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.getProcessMessageButtonByIndex; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.getProcessStatusByIndex; -import cucumber.api.java8.En; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; -import javax.inject.Inject; -import lombok.extern.slf4j.Slf4j; -import org.openqa.selenium.Keys; -import org.openqa.selenium.interactions.Actions; -import org.sormas.e2etests.helpers.AssertHelpers; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.steps.BaseSteps; -import org.testng.Assert; -import org.testng.asserts.SoftAssert; - @Slf4j public class MessagesDirectorySteps implements En { @@ -379,5 +381,14 @@ public MessagesDirectorySteps( "Disease variant is not empty"); softly.assertAll(); }); + + And( + "^I check if report side component in Edit Case has specific date from the demis message$", + () -> { + softly.assertTrue( + webDriverHelpers.isElementPresent( + checkTextInReportSideComponent("27.09.2020"))); + softly.assertAll(); + }); } } diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index 89d55b70c76..db007a9f07e 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -524,7 +524,7 @@ Scenario: Create and send laboratory request via Demis Then I check that lab sample id match "second" specimen id from Demis message on Edit Sample page And I validate the existence of "1" pathogen tests And I back to the case from Edit Sample page DE - And I check if report side component in Edit Case has today date + And I check if report side component in Edit Case has specific date from the demis message When I click on edit Report on Edit Case page And I click on discard button And I click on Display associated external messages button from Reports side component From ff66d7f5d5c3ad6aab3c17234c65061a66549c24 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Wed, 26 Jul 2023 10:04:40 +0200 Subject: [PATCH 120/174] qu-auto/SORQA-1049 Stabilize "Demis - Process a Lab message that has multiple samples". Report side component date checking method has been removed. --- .../application/messages/MessagesDirectorySteps.java | 10 ---------- .../resources/features/sanity/web/DemisWeb.feature | 1 - 2 files changed, 11 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java index 377a259aeee..9d2c9a81b65 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java @@ -17,7 +17,6 @@ import java.util.List; import java.util.concurrent.TimeUnit; -import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.checkTextInReportSideComponent; import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.ACTION_CONFIRM_POPUP_BUTTON; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.ACTION_YES_BUTTON; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CLOSE_POPUP; @@ -381,14 +380,5 @@ public MessagesDirectorySteps( "Disease variant is not empty"); softly.assertAll(); }); - - And( - "^I check if report side component in Edit Case has specific date from the demis message$", - () -> { - softly.assertTrue( - webDriverHelpers.isElementPresent( - checkTextInReportSideComponent("27.09.2020"))); - softly.assertAll(); - }); } } diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index db007a9f07e..c70748d1ff3 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -524,7 +524,6 @@ Scenario: Create and send laboratory request via Demis Then I check that lab sample id match "second" specimen id from Demis message on Edit Sample page And I validate the existence of "1" pathogen tests And I back to the case from Edit Sample page DE - And I check if report side component in Edit Case has specific date from the demis message When I click on edit Report on Edit Case page And I click on discard button And I click on Display associated external messages button from Reports side component From 5fb350fe495dfbee1946e7dbe42021c9cd0efd10 Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Wed, 26 Jul 2023 11:37:34 +0300 Subject: [PATCH 121/174] #12025 - Add an environment list for the mobile app - changes after review --- .../symeda/sormas/app/backend/common/DatabaseHelper.java | 6 ++++++ .../sormas/app/backend/environment/Environment.java | 2 +- .../sormas/app/backend/environment/EnvironmentDao.java | 6 +++--- .../de/symeda/sormas/app/rest/SynchronizeDataAsync.java | 2 +- .../main/java/de/symeda/sormas/app/util/ViewHelper.java | 9 +++++++++ .../main/res/layout/row_environment_list_item_layout.xml | 4 ++-- 6 files changed, 22 insertions(+), 7 deletions(-) diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java index 66dd667ae0b..a941f5b16da 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java @@ -3061,6 +3061,12 @@ public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int + "externalId varchar(255), responsibleUser_id BIGINT REFERENCES users(id), investigationStatus varchar(255), environmentMedia varchar(255), " + "waterType varchar(255), otherWaterType text, infrastructureDetails varchar(255), otherInfrastructureDetails text, waterUse text, " + "otherWaterUse text, location_id BIGINT, UNIQUE(snapshot, uuid));"); + + case 345: + currentVersion = 345; + getDao(EnvironmentDao.class).executeRaw("ALTER TABLE environments uuid VARCHAR(36) NOT NULL UNIQUE"); + getDao(EnvironmentDao.class).executeRaw("ALTER TABLE environments reportDate TIMESTAMP NOT NULL"); + // ATTENTION: break should only be done after last version break; diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/Environment.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/Environment.java index a1dc71b7c56..1eaf891ea22 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/Environment.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/Environment.java @@ -77,7 +77,7 @@ public class Environment extends AbstractDomainObject { private EnvironmentInfrastructureDetails infrastructureDetails; @Column(length = CHARACTER_LIMIT_TEXT) private String otherInfrastructureDetails; - @Column(name = "wateruse", length = 1024) + @Column(name = "waterUse", length = 1024) private String waterUseJson; private Map wateruse; @Column(length = CHARACTER_LIMIT_TEXT) diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/EnvironmentDao.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/EnvironmentDao.java index 9960a9efaa0..c0a09c80592 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/EnvironmentDao.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/environment/EnvironmentDao.java @@ -34,7 +34,7 @@ public List getAll() { QueryBuilder queryBuilder = queryBuilder(); return queryBuilder.orderBy(Environment.CHANGE_DATE, false).query(); } catch (SQLException e) { - Log.e(getTableName(), "Could not perform getAllActive on Environment"); + Log.e(getTableName(), "Could not perform getAllActive on Environment", e); throw new RuntimeException(); } } @@ -43,7 +43,7 @@ public long countByCriteria(EnvironmentCriteria criteria) { try { return buildQueryBuilder(criteria).countOf(); } catch (SQLException e) { - Log.e(getTableName(), "Could not perform countByCriteria on Environment"); + Log.e(getTableName(), "Could not perform countByCriteria on Environment", e); throw new RuntimeException(); } } @@ -52,7 +52,7 @@ public List queryByCriteria(EnvironmentCriteria criteria, long offs try { return buildQueryBuilder(criteria).orderBy(Environment.LOCAL_CHANGE_DATE, false).offset(offset).limit(limit).query(); } catch (SQLException e) { - Log.e(getTableName(), "Could not perform queryByCriteria on Environment"); + Log.e(getTableName(), "Could not perform queryByCriteria on Environment", e); throw new RuntimeException(); } } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/SynchronizeDataAsync.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/SynchronizeDataAsync.java index 3d2b2b7db3b..2d27931794c 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/SynchronizeDataAsync.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/SynchronizeDataAsync.java @@ -147,7 +147,7 @@ protected Void doInBackground(Void... params) { try { boolean pullAndRemoveObsoleteNecessary = ConfigProvider.getLastObsoleteUuidsSyncDate() == null - || DateHelper.getFullDaysBetween(ConfigProvider.getLastObsoleteUuidsSyncDate(), new Date()) >= 0; + || DateHelper.getFullDaysBetween(ConfigProvider.getLastObsoleteUuidsSyncDate(), new Date()) >= 1; syncCallbacks .ifPresent(c -> c.getUpdateStepNumberCallback().accept(syncMode == SyncMode.Changes ? pullAndRemoveObsoleteNecessary ? 5 : 4 : 6)); syncCallbacks.ifPresent(c -> c.getShowDialogCallback().run()); diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/util/ViewHelper.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/util/ViewHelper.java index dc62957f19b..3d89342317a 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/util/ViewHelper.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/util/ViewHelper.java @@ -25,6 +25,7 @@ import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.app.R; +import de.symeda.sormas.app.backend.location.Location; /** * Created by Orson on 30/12/2017. @@ -65,4 +66,12 @@ public static void removeInaccessibleTextViewFormat(TextView textField) { textField.setTextColor(textField.getContext().getResources().getColor(R.color.listActivityRowPrimaryText)); textField.setTypeface(null, Typeface.NORMAL); } + + public static String getLatLonLocation(Location location) { + if (location == null || location.getLatLonString().isEmpty()) { + return null; + } else { + return "GPS: " + location.getLatLonString(); + } + } } diff --git a/sormas-app/app/src/main/res/layout/row_environment_list_item_layout.xml b/sormas-app/app/src/main/res/layout/row_environment_list_item_layout.xml index cb1da078710..0376ec2a74f 100644 --- a/sormas-app/app/src/main/res/layout/row_environment_list_item_layout.xml +++ b/sormas-app/app/src/main/res/layout/row_environment_list_item_layout.xml @@ -22,7 +22,7 @@ - + From bd012a590d5cc57188de11dfd83593a2d893e626 Mon Sep 17 00:00:00 2001 From: Michal Kozakiewicz Date: Wed, 26 Jul 2023 10:49:14 +0200 Subject: [PATCH 122/174] SORQA-1046 Implementation "Re-send Case to Survnet" - refactoring --- .../application/cases/CaseDirectorySteps.java | 102 +----------------- .../features/sanity/web/Survnet.feature | 2 - 2 files changed, 4 insertions(+), 100 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDirectorySteps.java index 84a3bc205d1..e7ed618c9e9 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDirectorySteps.java @@ -19,104 +19,9 @@ package org.sormas.e2etests.steps.web.application.cases; import static org.sormas.e2etests.entities.pojo.helpers.ShortUUIDGenerator.generateShortUUID; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.ACTION_OKAY; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.ACTION_RESET_POPUP; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.ACTION_SEARCH_POPUP; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.ALLBUTTON; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.ALL_RESULTS_CHECKBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.BULK_ACTIONS; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.BULK_ACTIONS_ARCHIVE; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.BULK_ACTIONS_VALUES; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.BULK_CREATE_QUARANTINE_ORDER; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.BULK_EDIT_INFORMATION; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASES_FROM_OTHER_INSTANCES_CHECKBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASES_FROM_OTHER_JURISDICTIONS_CHECKBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASES_HELP_NEEDED_IN_QUARANTINE_CHECKBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASES_WITHOUT_FACILITY_CHECKBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASES_WITHOUT_GEO_COORDINATES_CHECKBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASES_WITHOUT_RESPONSIBLE_OFFICER_CHECKBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASES_WITH_EVENTS_CHECKBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASES_WITH_EXTENDED_QUARANTINE_CHECKBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASES_WITH_FULFILLED_REFERENCE_DEFINITION_CHECKBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASES_WITH_REDUCED_QUARANTINE_CHECKBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASES_WITH_REINFECTION_CHECKBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_APPLY_FILTERS_BUTTON; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_ARCHIVED_POPUP; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_CLASSIFICATION_FILTER_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_COMMUNITY_FILTER_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_DATA_TYPE_FILTER_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_DAY_FILTER; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_DIRECTORY_DETAILED_PAGE_APPLY_FILTER_BUTTON; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_DIRECTORY_DETAILED_PAGE_FILTER_INPUT; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_DIRECTORY_DETAILED_RADIOBUTTON; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_DISEASE_FILTER_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_DISEASE_VARIANT_FILTER_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_DISPLAY_FILTER_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_DISTRICT_FILTER_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_EPIDEMIOLOGICAL_DATA_TAB; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_FACILITY_CATEGORY_FILTER_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_FACILITY_FILTER_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_FACILITY_TYPE_FILTER_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_FOLLOWUP_FILTER_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_GRID_RESULTS_ROWS; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_MONTH_FILTER; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_ORIGIN_FILTER_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_OUTCOME_FILTER_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_OWNERSHIP_FILTER_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_PRESENT_CONDITION_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_QUARANTINE_FILTER_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_REGION_FILTER_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_REINFECTION_FILTER_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_REPORTING_USER_FILTER; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_RESET_FILTERS_BUTTON; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_SURVOFF_FILTER_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_VACCINATION_STATUS_FILTER_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_YEAR_FILTER; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CLOSE_FORM_BUTTON; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CONFIRM_POPUP; +import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.*; import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CREATE_NEW_PERSON_CHECKBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.DATE_FROM_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.DATE_TO_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.DATE_TYPE_FILTER_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.DETAILED_IMPORT_BUTTON; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.DOWNLOAD_DATA_DICTIONARY_BUTTON; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.DOWNLOAD_IMPORT_GUIDE_BUTTON; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.ENTER_BULK_EDIT_MODE; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.EPI_DATA_TAB; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.EXCLAMATION_MARK_MESSAGE_PICK_OR_CREATE_PERSON_POPUP; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.EXCLAMATION_MARK_PICK_OR_CREATE_PERSON_POPUP; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.FIRST_CASE_ID_BUTTON; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.FIRST_RESULT_IN_GRID; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.GRID_HEADERS; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.IMPORT_BUTTON; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.INVESTIGATION_DISCARDED_BUTTON; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.INVESTIGATION_DONE_BUTTON; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.INVESTIGATION_PENDING_BUTTON; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.LEAVE_BULK_EDIT_MODE; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.LINE_LISTING_BUTTON; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.MERGE_DUPLICATES_BUTTON; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.MERGE_DUPLICATES_WARNING_POPUP; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.MORE_BUTTON; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.NAME_UUID_EPID_NUMBER_LIKE_INPUT; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.NEW_CASE_BUTTON; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.NEW_CASE_DATE_FROM_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.NEW_EVENT_CHECKBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.PERSON_ID_NAME_CONTACT_INFORMATION_LIKE_INPUT; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.POTENTIAL_DUPLICATE_POPUP_DE; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.REJECT_SHARED_CASE_HEADER_DE; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.REJECT_SHARED_CASE_POPUP_TEXT_AREA; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.RESULTS_GRID_HEADER; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.SEARCH_BUTTON; import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.SEND_TO_REPORTING_TOOL_BUTTON; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.SHARE_OPTION_BULK_ACTION_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.SHOW_MORE_LESS_FILTERS; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.TOTAL_CASES_COUNTER; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.UPLOAD_DOCUMENT_TO_ENTITIES_CHECKBOX; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.getCaseResultsUuidLocator; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.getCheckboxByIndex; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.getMergeDuplicatesButtonById; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.getResultByIndex; -import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.getVaccinationStatusCasesByText; import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.DATE_OF_REPORT_INPUT; import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.SAVE_BUTTON; import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.UUID_EXTERNAL_ID_EXTERNAL_TOKEN_LIKE_INPUT; @@ -1094,14 +999,15 @@ public CaseDirectorySteps( webDriverHelpers.checkIfElementExistsInCombobox( CASE_DISPLAY_FILTER_COMBOBOX, caseParameter); webDriverHelpers.selectFromCombobox(CASE_DISPLAY_FILTER_COMBOBOX, caseParameter); - TimeUnit.SECONDS.sleep(2); + webDriverHelpers.waitUntilElementIsVisibleAndClickable(FIRST_CASE_ID); }); When( "I validate the existence of {string} Reporting Tools entries in Survnet box", (String number) -> { int numberInt = Integer.parseInt(number); - TimeUnit.SECONDS.sleep(2); + webDriverHelpers.waitUntilElementIsVisibleAndClickable( + EditCasePage.SEND_TO_REPORTING_TOOL_BUTTON); softly.assertEquals( webDriverHelpers.getNumberOfElements(REPORTING_TOOLS_FOR_SURVNET_USER), numberInt, diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature index 995aabb6733..171b7513d65 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature @@ -354,7 +354,6 @@ Feature: Survnet tests When I click on the Cases button from navbar And I click on the NEW CASE button And I create a new case with mandatory data only for Survnet DE - Then I get the case person UUID displayed on Edit case page And I click on Send to reporting tool button on Edit Case page Then I check that Reporting tool in Survnet box contain "gesendet am" entry And I delete the case for DE @@ -365,7 +364,6 @@ Feature: Survnet tests Then I click on Restore button from case And I apply "Aktive Fälle" to combobox on Case Directory Page And I click on the first Case ID from Case Directory - Then I get the case person UUID displayed on Edit case page And I click on Send to reporting tool button on Edit Case page Then I click on the Archive case button Then I check the end of processing date in the archive popup and select Archive contacts checkbox for DE From d8352013dc274eb78f3ce5d179a9eb31878a7744 Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Wed, 26 Jul 2023 13:03:02 +0300 Subject: [PATCH 123/174] #12025 - Add an environment list for the mobile app - changes after review --- .../row_environment_list_item_layout.xml | 44 ++++++++++++++++--- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/sormas-app/app/src/main/res/layout/row_environment_list_item_layout.xml b/sormas-app/app/src/main/res/layout/row_environment_list_item_layout.xml index 0376ec2a74f..79a8b688d64 100644 --- a/sormas-app/app/src/main/res/layout/row_environment_list_item_layout.xml +++ b/sormas-app/app/src/main/res/layout/row_environment_list_item_layout.xml @@ -27,7 +27,7 @@ - + @@ -104,12 +104,11 @@ android:orientation="vertical" > - + + + + + + + + + + + + + - + + android:textSize="@dimen/row_entry_secondary_text_size" + app:value="@{data.investigationStatus}" /> Date: Wed, 26 Jul 2023 11:03:42 +0000 Subject: [PATCH 124/174] [GitHub Actions] Update openAPI spec files --- sormas-rest/swagger.json | 40 +++++++++++++++++++++++++++++++++++----- sormas-rest/swagger.yaml | 31 ++++++++++++++++++++++++++----- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/sormas-rest/swagger.json b/sormas-rest/swagger.json index 84142ff473e..346f6e4ed2b 100644 --- a/sormas-rest/swagger.json +++ b/sormas-rest/swagger.json @@ -3856,6 +3856,36 @@ "tags" : [ "Environment Controller" ] } }, + "/environments/obsolete/{since}" : { + "get" : { + "operationId" : "getObsoleteUuidsSince_2", + "parameters" : [ { + "in" : "path", + "name" : "since", + "required" : true, + "schema" : { + "type" : "integer", + "format" : "int64" + } + } ], + "responses" : { + "default" : { + "content" : { + "application/json; charset=UTF-8" : { + "schema" : { + "type" : "array", + "items" : { + "type" : "string" + } + } + } + }, + "description" : "default response" + } + }, + "tags" : [ "Environment Controller" ] + } + }, "/environments/push" : { "post" : { "description" : "A uuid will be generated for any entity that doesn't have one yet. Posting entities without uuid multiple times will also create them multiple times.", @@ -4331,7 +4361,7 @@ }, "/eventparticipants/obsolete/{since}" : { "get" : { - "operationId" : "getObsoleteUuidsSince_2", + "operationId" : "getObsoleteUuidsSince_3", "parameters" : [ { "in" : "path", "name" : "since", @@ -4815,7 +4845,7 @@ }, "/events/obsolete/{since}" : { "get" : { - "operationId" : "getObsoleteUuidsSince_3", + "operationId" : "getObsoleteUuidsSince_4", "parameters" : [ { "in" : "path", "name" : "since", @@ -5663,7 +5693,7 @@ }, "/immunizations/obsolete/{since}" : { "get" : { - "operationId" : "getObsoleteUuidsSince_4", + "operationId" : "getObsoleteUuidsSince_5", "parameters" : [ { "in" : "path", "name" : "since", @@ -7808,7 +7838,7 @@ }, "/samples/obsolete/{since}" : { "get" : { - "operationId" : "getObsoleteUuidsSince_5", + "operationId" : "getObsoleteUuidsSince_6", "parameters" : [ { "in" : "path", "name" : "since", @@ -8968,7 +8998,7 @@ }, "/tasks/obsolete/{since}" : { "get" : { - "operationId" : "getObsoleteUuidsSince_6", + "operationId" : "getObsoleteUuidsSince_7", "parameters" : [ { "in" : "path", "name" : "since", diff --git a/sormas-rest/swagger.yaml b/sormas-rest/swagger.yaml index b76a7d71992..45f015933fa 100644 --- a/sormas-rest/swagger.yaml +++ b/sormas-rest/swagger.yaml @@ -2716,6 +2716,27 @@ paths: description: default response tags: - Environment Controller + /environments/obsolete/{since}: + get: + operationId: getObsoleteUuidsSince_2 + parameters: + - in: path + name: since + required: true + schema: + type: integer + format: int64 + responses: + default: + content: + application/json; charset=UTF-8: + schema: + type: array + items: + type: string + description: default response + tags: + - Environment Controller /environments/push: post: description: A uuid will be generated for any entity that doesn't have one yet. @@ -3055,7 +3076,7 @@ paths: - Event Participant Controller /eventparticipants/obsolete/{since}: get: - operationId: getObsoleteUuidsSince_2 + operationId: getObsoleteUuidsSince_3 parameters: - in: path name: since @@ -3385,7 +3406,7 @@ paths: - Event Controller /events/obsolete/{since}: get: - operationId: getObsoleteUuidsSince_3 + operationId: getObsoleteUuidsSince_4 parameters: - in: path name: since @@ -4030,7 +4051,7 @@ paths: - Immunization Controller /immunizations/obsolete/{since}: get: - operationId: getObsoleteUuidsSince_4 + operationId: getObsoleteUuidsSince_5 parameters: - in: path name: since @@ -5577,7 +5598,7 @@ paths: - Sample Controller /samples/obsolete/{since}: get: - operationId: getObsoleteUuidsSince_5 + operationId: getObsoleteUuidsSince_6 parameters: - in: path name: since @@ -6365,7 +6386,7 @@ paths: - Task Controller /tasks/obsolete/{since}: get: - operationId: getObsoleteUuidsSince_6 + operationId: getObsoleteUuidsSince_7 parameters: - in: path name: since From 900b2e87433826a8c09212fa0958c78d0a812e59 Mon Sep 17 00:00:00 2001 From: Martin Wahnschaffe Date: Wed, 26 Jul 2023 14:49:10 +0200 Subject: [PATCH 125/174] #11981 added readme to explain source of default infrastructure data --- sormas-backend/src/main/resources/README.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 sormas-backend/src/main/resources/README.md diff --git a/sormas-backend/src/main/resources/README.md b/sormas-backend/src/main/resources/README.md new file mode 100644 index 00000000000..86b609eb0d0 --- /dev/null +++ b/sormas-backend/src/main/resources/README.md @@ -0,0 +1,5 @@ +# SORMAS Backend Resources + +## Infrastructure Data + +The infrastructure default import files for continents, sub-continents and countries are copied from [SORMAS-central-data](https://github.com/SORMAS-Foundation/SORMAS-central-data/tree/main/out/international). \ No newline at end of file From 9ab2cc97b89e72b902d4d9363841b67989277dc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=A9=20Strysewske?= Date: Thu, 27 Jul 2023 09:37:56 +0200 Subject: [PATCH 126/174] #12068 - Enforce result limit --- .../main/java/de/symeda/sormas/backend/caze/CaseService.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseService.java index 9933263c989..da43647db77 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseService.java @@ -2072,6 +2072,11 @@ public List getCasesForDuplicateMerging( em.createQuery(indexCasesCq).getResultStream().collect(Collectors.toMap(c -> c.getId(), Function.identity())); for (Object[] idPair : foundIds) { + // Abort the operation if the limit has been reached + if (limit != null && resultIdsSet.size() >= limit) { + break; + } + // Skip duplicate pairs - duplications always happen in reverse order, i.e. if idPair[0]/idPair[1] // is already in the result set in this order, the duplication would be added as idPair[1]/idPair[0] if (resultIdsSet.contains(new AbstractMap.SimpleImmutableEntry<>(idPair[1], idPair[0]))) { From 6946648305a89a79f3cfbe348c86942e69a7e934 Mon Sep 17 00:00:00 2001 From: Martin Wahnschaffe Date: Thu, 27 Jul 2023 09:41:53 +0200 Subject: [PATCH 127/174] #12243 process documentation for automatic dependency update PRs (#12342) * #12243 process documentation for automatic dependency update PRs * #12243 fixed typo and included micro version updates --- docs/CONTRIBUTING.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 7ee8a9d0f67..a70b9951e8a 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -22,6 +22,7 @@ This allows us to consider and process your contribution as quickly and smoothly * [Development Workflow](#development-workflow) * [Versioning](#versioning) * [Branches](#branches) + * [Dependency Management](#dependency-management) ## Submitting an Issue @@ -226,3 +227,26 @@ Once the new version is merged to `master`/`master- Date: Thu, 27 Jul 2023 10:14:57 +0200 Subject: [PATCH 128/174] SORQA-1045 Stabilize "[S2S] Sample and Immunization - Add sample and immunization in target system" - increased sleep time in "I back to tab number" method --- .../org/sormas/e2etests/steps/web/application/LoginSteps.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/LoginSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/LoginSteps.java index f8bcccfbae6..991c22354af 100755 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/LoginSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/LoginSteps.java @@ -142,7 +142,7 @@ public LoginSteps( "I back to tab number {int}", (Integer tabNo) -> { webDriverHelpers.switchToTheTabNumber(tabNo); - TimeUnit.SECONDS.sleep(2); + TimeUnit.SECONDS.sleep(5); }); Then( "I login with last edited user", From dee8efb09677fb893cea30bb0647146ccbb4c1bd Mon Sep 17 00:00:00 2001 From: Razvan Date: Fri, 28 Jul 2023 10:07:32 +0300 Subject: [PATCH 129/174] SORQA-1050 : refactored code --- .../immunizations/VaccineNameValues.java | 2 +- .../aCommonComponents/SideCards.java | 6 + .../pages/application/cases/EditCasePage.java | 7 - .../messages/MessagesDirectoryPage.java | 7 +- .../application/samples/EditSamplePage.java | 4 +- .../src/main/java/recorders/StepsLogger.java | 3 +- .../entities/services/EventService.java | 3 +- .../services/api/demis/DemisApiService.java | 20 +- .../steps/api/demisSteps/DemisSteps.java | 67 ++++--- .../aCommonComponents/SideCardsSteps.java | 71 ++++--- .../application/cases/CreateNewCaseSteps.java | 63 +++--- .../web/application/cases/EditCaseSteps.java | 24 --- .../contacts/EditContactSteps.java | 9 - .../events/CreateNewEventSteps.java | 55 +++--- .../application/events/EditEventSteps.java | 105 +++++----- .../samples/CreateNewSampleSteps.java | 55 +++--- .../application/samples/EditSampleSteps.java | 63 +++--- .../web/application/survnet/SurvNetSteps.java | 182 +++++++++--------- .../features/sanity/web/SharedCases.feature | 154 +++++++-------- .../sanity/web/SharedContacts.feature | 60 +++--- .../features/sanity/web/SharedPersons.feature | 18 +- 21 files changed, 485 insertions(+), 493 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/immunizations/VaccineNameValues.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/immunizations/VaccineNameValues.java index 14044a2272c..1dac65281ee 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/immunizations/VaccineNameValues.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/immunizations/VaccineNameValues.java @@ -44,4 +44,4 @@ public enum VaccineNameValues { public static String getRandomVaccineName() { return String.valueOf(VaccineNameValues.values()[random.nextInt(values().length)].vaccineName); } -} \ No newline at end of file +} diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/aCommonComponents/SideCards.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/aCommonComponents/SideCards.java index 15630cb1175..dc1289349b0 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/aCommonComponents/SideCards.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/aCommonComponents/SideCards.java @@ -22,6 +22,11 @@ public class SideCards { + public static final By SHARE_SORMAS_2_SORMAS_BUTTON = By.cssSelector("#sormasToSormasShare"); + public static final By SHARE_ORGANIZATION_POPUP_COMBOBOX = + By.cssSelector(".popupContent #organization div"); + public static final By HAND_THE_OWNERSHIP_CHECKBOX = + By.cssSelector(".popupContent #handOverOwnership label"); public static final By ADDED_SAMPLES_IN_SAMPLE_CARD = By.xpath("//*[@location='samples']//*[@class='v-slot v-slot-s-list']/div/div/div/div"); public static final By EDIT_SAMPLE_BUTTON = By.xpath("//div[contains(@id, 'edit-sample')]"); @@ -58,6 +63,7 @@ public static By checkTextInReportSideComponent(String text) { "//div[@location='sormasToSormas']//div[@class='v-slot v-slot-s-list-entry v-slot-s-list-entry-no-border']"); public static final By SHARE_SORMAS_2_SORMAS_POPUP_BUTTON = By.cssSelector(".popupContent #commit"); + public static By getEditSampleButtonByNumber(Integer number) { return By.xpath(String.format("(//div[contains(@id, 'edit-sample')])[%x]", number)); } diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/EditCasePage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/EditCasePage.java index 8a31e04ad27..941569a07a6 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/EditCasePage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/EditCasePage.java @@ -366,13 +366,6 @@ public static By getByImmunizationUuid(String immunizationUuid) { By.xpath("//div[@class='v-window-outerheader']"); public static final By PLACE_OF_STAY_REGION_INPUT = By.cssSelector("#region input"); public static final By PLACE_OF_STAY_DISTRICT_INPUT = By.cssSelector("#district input"); - - public static final By SHARE_SORMAS_2_SORMAS_BUTTON = By.cssSelector("#sormasToSormasShare"); - public static final By SHARE_ORGANIZATION_POPUP_COMBOBOX = - By.cssSelector(".popupContent #organization div"); - public static final By HAND_THE_OWNERSHIP_CHECKBOX = - By.cssSelector(".popupContent #handOverOwnership label"); - public static final By SAHRE_SAMPLES_CHECKBOX = By.cssSelector(".popupContent #withSamples label"); public static final By SHARE_IMMUNIZATION_CHECKBOX = diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java index b3f159eb3ce..3b0b095cbeb 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java @@ -138,6 +138,9 @@ public static By getProcessStatusByIndex(int index) { By.xpath("(//input[contains(@id, 'labDetails')])[2]"); public static final By NEW_SAMPLE_FORM_SECOND_PATHOGEN_LABORATORY_NAME = By.xpath("(//input[contains(@id, 'labDetails')])[3]"); - public static final By MULTIPLE_SAMPLES_HEADER = By.xpath("//div[@class= 'v-window-header'][text()='Mehrere Proben']"); - public static final By CREATE_NEW_SAMPLE_CHECKBOX = By.xpath("//span[@class= 'v-radiobutton v-select-option']//label[text()='Neue Probe erstellen']"); + public static final By MULTIPLE_SAMPLES_HEADER = + By.xpath("//div[@class= 'v-window-header'][text()='Mehrere Proben']"); + public static final By CREATE_NEW_SAMPLE_CHECKBOX = + By.xpath( + "//span[@class= 'v-radiobutton v-select-option']//label[text()='Neue Probe erstellen']"); } diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/samples/EditSamplePage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/samples/EditSamplePage.java index dabd5c0aa14..7a03df77461 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/samples/EditSamplePage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/samples/EditSamplePage.java @@ -81,5 +81,7 @@ public class EditSamplePage { By.cssSelector("[class='popupContent'] [id='pcrTestSpecification'] input"); public static final By SEE_SAMPLES_FOR_THIS_PERSON_BUTTON_DE = By.id("Proben f\u00FCr diese Person ansehen"); - public static final By BACK_TO_CASE_DE_BUTTON = By.xpath("//div[@class='v-link v-widget v-caption v-link-v-caption']//span[contains(text(), 'Fall')]"); + public static final By BACK_TO_CASE_DE_BUTTON = + By.xpath( + "//div[@class='v-link v-widget v-caption v-link-v-caption']//span[contains(text(), 'Fall')]"); } diff --git a/sormas-e2e-tests/src/main/java/recorders/StepsLogger.java b/sormas-e2e-tests/src/main/java/recorders/StepsLogger.java index c3573ab185e..26b0378867b 100644 --- a/sormas-e2e-tests/src/main/java/recorders/StepsLogger.java +++ b/sormas-e2e-tests/src/main/java/recorders/StepsLogger.java @@ -115,8 +115,7 @@ public void takeScreenshot() { @SneakyThrows private List collectWarningElements() { - List warningsList = - driver.findElements(By.xpath("//*[contains(@class,'error')]")); + List warningsList = driver.findElements(By.xpath("//*[contains(@class,'error')]")); List attachments = new ArrayList<>(); String fileName = "warning_element%s.jpg"; for (int i = 0; i < warningsList.size(); i++) { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/EventService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/EventService.java index 1096ab103a0..a026d51c191 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/EventService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/EventService.java @@ -17,14 +17,13 @@ import com.github.javafaker.Faker; import com.google.inject.Inject; +import java.time.LocalDate; import org.sormas.e2etests.entities.pojo.web.Event; import org.sormas.e2etests.enums.CommunityValues; import org.sormas.e2etests.enums.DiseasesValues; import org.sormas.e2etests.enums.DistrictsValues; import org.sormas.e2etests.enums.RegionsValues; -import java.time.LocalDate; - public class EventService { private final Faker faker; diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java index bd9acd9ca2f..dcdaaa2f2ba 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java @@ -17,6 +17,13 @@ */ package org.sormas.e2etests.entities.services.api.demis; +import static org.sormas.e2etests.steps.BaseSteps.locale; + +import java.net.SocketTimeoutException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.UUID; +import javax.inject.Inject; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import okhttp3.MediaType; @@ -30,14 +37,6 @@ import org.sormas.e2etests.envconfig.manager.RunningConfiguration; import org.sormas.e2etests.helpers.api.demis.okhttpclient.SormasOkHttpClient; -import javax.inject.Inject; -import java.net.SocketTimeoutException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.UUID; - -import static org.sormas.e2etests.steps.BaseSteps.locale; - @Slf4j public class DemisApiService { @@ -259,9 +258,10 @@ public String prepareLabNotificationFileWithTwoSamples( } public String prepareLabNotificationFileWithOneExistingFacility( - String patientFirstName, String patientLastName) { + String patientFirstName, String patientLastName) { DemisData demisData = runningConfiguration.getDemisData(locale); - String file = "src/main/resources/demisJsonTemplates/labNotificationTemplateWithExistingFacility.json"; + String file = + "src/main/resources/demisJsonTemplates/labNotificationTemplateWithExistingFacility.json"; String json = readFileAsString(file); json = json.replace("", UUID.randomUUID().toString()); json = json.replace("\"\"", "\"" + patientLastName + "\""); diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java index 57616effba6..0e43be8ae09 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java @@ -1,35 +1,5 @@ package org.sormas.e2etests.steps.api.demisSteps; -import com.github.javafaker.Faker; -import cucumber.api.java8.En; -import lombok.extern.slf4j.Slf4j; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; -import org.sormas.e2etests.entities.pojo.web.Event; -import org.sormas.e2etests.entities.services.EventService; -import org.sormas.e2etests.entities.services.api.demis.DemisApiService; -import org.sormas.e2etests.envconfig.dto.demis.DemisData; -import org.sormas.e2etests.envconfig.manager.RunningConfiguration; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.steps.BaseSteps; -import org.sormas.e2etests.steps.web.application.messages.MessagesTableViewHeaders; -import org.testng.Assert; -import org.testng.asserts.SoftAssert; - -import javax.inject.Inject; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.PERSON_ID_NAME_CONTACT_INFORMATION_LIKE_INPUT; import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.DATE_OF_REPORT_INPUT; import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.FIRST_NAME_INPUT; @@ -105,6 +75,35 @@ import static org.sormas.e2etests.pages.application.samples.EditSamplePage.PCR_TEST_SPECIFICATION_INPUT; import static org.sormas.e2etests.steps.BaseSteps.locale; +import com.github.javafaker.Faker; +import cucumber.api.java8.En; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.sormas.e2etests.entities.pojo.web.Event; +import org.sormas.e2etests.entities.services.EventService; +import org.sormas.e2etests.entities.services.api.demis.DemisApiService; +import org.sormas.e2etests.envconfig.dto.demis.DemisData; +import org.sormas.e2etests.envconfig.manager.RunningConfiguration; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.steps.BaseSteps; +import org.sormas.e2etests.steps.web.application.messages.MessagesTableViewHeaders; +import org.testng.Assert; +import org.testng.asserts.SoftAssert; + @Slf4j public class DemisSteps implements En { @@ -940,9 +939,13 @@ public DemisSteps( () -> { patientFirstName = faker.name().firstName(); patientLastName = faker.name().lastName(); - String json = demisApiService.prepareLabNotificationFileWithOneExistingFacility(patientFirstName, patientLastName); + String json = + demisApiService.prepareLabNotificationFileWithOneExistingFacility( + patientFirstName, patientLastName); - Assert.assertTrue(demisApiService.sendLabRequest(json, loginToken), "Failed to send laboratory request"); + Assert.assertTrue( + demisApiService.sendLabRequest(json, loginToken), + "Failed to send laboratory request"); }); } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/aCommonComponents/SideCardsSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/aCommonComponents/SideCardsSteps.java index 3d0527ac631..9663c21c349 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/aCommonComponents/SideCardsSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/aCommonComponents/SideCardsSteps.java @@ -18,33 +18,23 @@ package org.sormas.e2etests.steps.web.application.aCommonComponents; +import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.*; +import static org.sormas.e2etests.pages.application.contacts.EditContactPage.NUMBER_OF_TESTS_IN_SAMPLES; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.ONE_TEST_IN_SAMPLES_DE; + import com.github.javafaker.Faker; import cucumber.api.java8.En; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.concurrent.TimeUnit; +import javax.inject.Inject; import lombok.SneakyThrows; +import org.sormas.e2etests.envconfig.manager.RunningConfiguration; import org.sormas.e2etests.helpers.WebDriverHelpers; import org.sormas.e2etests.steps.BaseSteps; +import org.testng.Assert; import org.testng.asserts.SoftAssert; -import javax.inject.Inject; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.util.concurrent.TimeUnit; - -import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.ADDED_SAMPLES_IN_SAMPLE_CARD; -import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.EDIT_SAMPLE_BUTTON; -import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.HANDOVER_SIDE_CARD; -import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.LINKED_SHARED_ORGANIZATION_SELECTED_VALUE; -import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.REPORTS_DISPLAY_ASSOCIATED_EXTERNAL_MESSAGES_BUTTON; -import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.SAMPLES_DISPLAY_ASSOCIATED_LAB_MESSAGES_BUTTON; -import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.SHARE_SORMAS_2_SORMAS_POPUP_BUTTON; -import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.checkTextInHandoverSideComponent; -import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.checkTextInImmunizationSideComponent; -import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.checkTextInReportSideComponent; -import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.checkTextInSampleSideComponent; -import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.getEditSampleButtonByNumber; -import static org.sormas.e2etests.pages.application.contacts.EditContactPage.NUMBER_OF_TESTS_IN_SAMPLES; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.ONE_TEST_IN_SAMPLES_DE; - public class SideCardsSteps implements En { private final WebDriverHelpers webDriverHelpers; public static Faker faker; @@ -57,7 +47,11 @@ public class SideCardsSteps implements En { @SneakyThrows @Inject public SideCardsSteps( - WebDriverHelpers webDriverHelpers, SoftAssert softly, BaseSteps baseSteps, Faker faker) { + WebDriverHelpers webDriverHelpers, + SoftAssert softly, + BaseSteps baseSteps, + Faker faker, + RunningConfiguration runningConfiguration) { this.webDriverHelpers = webDriverHelpers; this.faker = faker; this.baseSteps = baseSteps; @@ -73,7 +67,40 @@ public SideCardsSteps( + webDriverHelpers.getTextFromPresentWebElement(HANDOVER_SIDE_CARD)); softly.assertAll(); }); - + When( + "I check if handover card contains shared with {string} information", + (String environmentIdentifier) -> { + webDriverHelpers.waitUntilIdentifiedElementIsVisibleAndClickable(HANDOVER_SIDE_CARD); + TimeUnit.SECONDS.sleep(3); + softly.assertTrue( + webDriverHelpers.isElementPresent( + checkTextInHandoverSideComponent( + runningConfiguration.getSurvnetResponsible(environmentIdentifier))), + environmentIdentifier + + " text is not present in handover component. Found only " + + webDriverHelpers.getTextFromPresentWebElement(HANDOVER_SIDE_CARD)); + softly.assertAll(); + }); + When( + "I click on share button", + () -> webDriverHelpers.clickOnWebElementBySelector(SHARE_SORMAS_2_SORMAS_BUTTON)); + When( + "I check if share button is unavailable", + () -> { + Assert.assertFalse( + webDriverHelpers.isElementPresent(SHARE_SORMAS_2_SORMAS_BUTTON), + "Share button is displayed"); + }); + When( + "I select organization to share with {string}", + (String organization) -> { + String survnetOrganization = runningConfiguration.getSurvnetResponsible(organization); + webDriverHelpers.selectFromCombobox( + SHARE_ORGANIZATION_POPUP_COMBOBOX, survnetOrganization); + }); + When( + "I click to hand over the ownership in Share popup", + () -> webDriverHelpers.clickOnWebElementBySelector(HAND_THE_OWNERSHIP_CHECKBOX)); When( "I check if sample card has {string} information", (String information) -> { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CreateNewCaseSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CreateNewCaseSteps.java index b20e80840d2..d2334eb78c5 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CreateNewCaseSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CreateNewCaseSteps.java @@ -18,38 +18,6 @@ package org.sormas.e2etests.steps.web.application.cases; -import com.github.javafaker.Faker; -import cucumber.api.java8.En; -import io.restassured.http.Method; -import lombok.SneakyThrows; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; -import org.sormas.e2etests.entities.pojo.api.Request; -import org.sormas.e2etests.entities.pojo.web.Case; -import org.sormas.e2etests.entities.services.CaseService; -import org.sormas.e2etests.enums.GenderValues; -import org.sormas.e2etests.helpers.RestAssuredClient; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.helpers.files.FilesHelper; -import org.sormas.e2etests.pages.application.cases.EditCasePage; -import org.sormas.e2etests.state.ApiState; -import org.sormas.e2etests.steps.BaseSteps; -import org.testng.asserts.SoftAssert; - -import javax.inject.Inject; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.time.format.TextStyle; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Random; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - import static org.sormas.e2etests.constants.api.Endpoints.CASES_PATH; import static org.sormas.e2etests.entities.pojo.helpers.ShortUUIDGenerator.generateShortUUID; import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_APPLY_FILTERS_BUTTON; @@ -163,6 +131,37 @@ import static org.sormas.e2etests.steps.web.application.contacts.CreateNewContactSteps.contact; import static org.sormas.e2etests.steps.web.application.persons.PersonDirectorySteps.personSharedForAllEntities; +import com.github.javafaker.Faker; +import cucumber.api.java8.En; +import io.restassured.http.Method; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.TextStyle; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import javax.inject.Inject; +import lombok.SneakyThrows; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.sormas.e2etests.entities.pojo.api.Request; +import org.sormas.e2etests.entities.pojo.web.Case; +import org.sormas.e2etests.entities.services.CaseService; +import org.sormas.e2etests.enums.GenderValues; +import org.sormas.e2etests.helpers.RestAssuredClient; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.helpers.files.FilesHelper; +import org.sormas.e2etests.pages.application.cases.EditCasePage; +import org.sormas.e2etests.state.ApiState; +import org.sormas.e2etests.steps.BaseSteps; +import org.testng.asserts.SoftAssert; + public class CreateNewCaseSteps implements En { private final WebDriverHelpers webDriverHelpers; diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java index b5a012fe072..41d82635bfd 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java @@ -127,7 +127,6 @@ import static org.sormas.e2etests.pages.application.cases.EditCasePage.GENERAL_COMMENT_TEXT_AREA; import static org.sormas.e2etests.pages.application.cases.EditCasePage.GENERATED_DOCUMENT_NAME; import static org.sormas.e2etests.pages.application.cases.EditCasePage.GENERATED_DOCUMENT_NAME_DE; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.HAND_THE_OWNERSHIP_CHECKBOX; import static org.sormas.e2etests.pages.application.cases.EditCasePage.HOME_BASED_QUARANTINE_POSSIBLE_OPTIONS; import static org.sormas.e2etests.pages.application.cases.EditCasePage.HOSPITALIZATION_TAB; import static org.sormas.e2etests.pages.application.cases.EditCasePage.IMMUNIZATION_CARD_IMMUNIZATION_PERIOD_LABEL; @@ -221,10 +220,8 @@ import static org.sormas.e2etests.pages.application.cases.EditCasePage.SEQUELAE_DETAILS; import static org.sormas.e2etests.pages.application.cases.EditCasePage.SEQUELAE_OPTIONS; import static org.sormas.e2etests.pages.application.cases.EditCasePage.SHARE_IMMUNIZATION_CHECKBOX; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.SHARE_ORGANIZATION_POPUP_COMBOBOX; import static org.sormas.e2etests.pages.application.cases.EditCasePage.SHARE_PENDING_WARNING_DE; import static org.sormas.e2etests.pages.application.cases.EditCasePage.SHARE_REPORTS_CHECKBOX; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.SHARE_SORMAS_2_SORMAS_BUTTON; import static org.sormas.e2etests.pages.application.cases.EditCasePage.SHOW_SAMPLE_BUTTON; import static org.sormas.e2etests.pages.application.cases.EditCasePage.SURVEILLANCE_OFFICER_FIELD_ABOVE_GENERAL_COMMENT; import static org.sormas.e2etests.pages.application.cases.EditCasePage.SYMPTOMS_TAB; @@ -2565,21 +2562,6 @@ public EditCaseSteps( webDriverHelpers.selectFromCombobox(VACCINATION_STATUS_COMBOBOX, vaccinationStatus); webDriverHelpers.clickOnWebElementBySelector(SAVE_BUTTON); }); - - When( - "I click on share case button", - () -> webDriverHelpers.clickOnWebElementBySelector(SHARE_SORMAS_2_SORMAS_BUTTON)); - - When( - "I select organization to share with {string}", - (String organization) -> { - String survnetOrganization = runningConfiguration.getSurvnetResponsible(organization); - webDriverHelpers.selectFromCombobox( - SHARE_ORGANIZATION_POPUP_COMBOBOX, survnetOrganization); - }); - When( - "I click to hand over the ownership of the case in Share popup", - () -> webDriverHelpers.clickOnWebElementBySelector(HAND_THE_OWNERSHIP_CHECKBOX)); When( "I click to share samples of the case in Share popup", () -> webDriverHelpers.clickOnWebElementBySelector(SAHRE_SAMPLES_CHECKBOX)); @@ -2749,12 +2731,6 @@ public EditCaseSteps( softly.assertFalse(webDriverHelpers.isElementPresent(REJECT_SHARED_CASE_BUTTON)); softly.assertAll(); }); - When( - "I check if share case button in Edit Case is unavailable", - () -> { - softly.assertFalse(webDriverHelpers.isElementPresent(SHARE_SORMAS_2_SORMAS_BUTTON)); - softly.assertAll(); - }); When( "I click on revoke share button", () -> { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/contacts/EditContactSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/contacts/EditContactSteps.java index 721a7634597..32c4d85f9bb 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/contacts/EditContactSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/contacts/EditContactSteps.java @@ -46,11 +46,9 @@ import static org.sormas.e2etests.pages.application.cases.EditCasePage.FOLLOW_UP_COMMENT_FIELD; import static org.sormas.e2etests.pages.application.cases.EditCasePage.GENERATED_DOCUMENT_NAME; import static org.sormas.e2etests.pages.application.cases.EditCasePage.GENERATED_DOCUMENT_NAME_DE; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.HAND_THE_OWNERSHIP_CHECKBOX; import static org.sormas.e2etests.pages.application.cases.EditCasePage.NEW_IMMUNIZATION_BUTTON; import static org.sormas.e2etests.pages.application.cases.EditCasePage.QUARANTINE_ORDER_COMBOBOX; import static org.sormas.e2etests.pages.application.cases.EditCasePage.SAVE_POPUP_CONTENT; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.SHARE_SORMAS_2_SORMAS_BUTTON; import static org.sormas.e2etests.pages.application.cases.EditCasePage.UPLOAD_DOCUMENT_CHECKBOX; import static org.sormas.e2etests.pages.application.cases.EditCasePage.USER_INFORMATION; import static org.sormas.e2etests.pages.application.cases.EditCasePage.UUID_INPUT; @@ -513,17 +511,10 @@ public EditContactSteps( TimeUnit.SECONDS.sleep(2); webDriverHelpers.waitForPageLoadingSpinnerToDisappear(30); }); - When( - "I click to hand over the ownership of the contact in Share popup", - () -> webDriverHelpers.clickOnWebElementBySelector(HAND_THE_OWNERSHIP_CHECKBOX)); When( "I click to accept potential duplicate in Shares Page", () -> webDriverHelpers.clickOnWebElementBySelector(ACTION_CONFIRM)); - - When( - "I click on share contact button", - () -> webDriverHelpers.clickOnWebElementBySelector(SHARE_SORMAS_2_SORMAS_BUTTON)); When( "^I click on ([^\"]*) radio button Contact Person tab$", (String buttonName) -> diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/CreateNewEventSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/CreateNewEventSteps.java index 712ed623944..1746d3f7dc7 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/CreateNewEventSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/CreateNewEventSteps.java @@ -18,34 +18,6 @@ package org.sormas.e2etests.steps.web.application.events; -import com.github.javafaker.Faker; -import com.opencsv.CSVParser; -import com.opencsv.CSVParserBuilder; -import com.opencsv.CSVReader; -import com.opencsv.CSVReaderBuilder; -import com.opencsv.exceptions.CsvException; -import cucumber.api.java8.En; -import lombok.extern.slf4j.Slf4j; -import org.sormas.e2etests.entities.pojo.web.Event; -import org.sormas.e2etests.entities.services.EventService; -import org.sormas.e2etests.enums.DistrictsValues; -import org.sormas.e2etests.enums.RegionsValues; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.testng.asserts.SoftAssert; - -import javax.inject.Inject; -import java.io.FileReader; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.time.LocalDate; -import java.time.LocalTime; -import java.time.format.DateTimeFormatter; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; - import static org.sormas.e2etests.pages.application.events.CreateNewEventPage.DISEASE_COMBOBOX; import static org.sormas.e2etests.pages.application.events.CreateNewEventPage.DISEASE_VARIANT_COMBOBOX; import static org.sormas.e2etests.pages.application.events.CreateNewEventPage.END_DATA_EVENT; @@ -75,6 +47,33 @@ import static org.sormas.e2etests.pages.application.events.EditEventPage.UUID_INPUT; import static org.sormas.e2etests.pages.application.events.EventDirectoryPage.NEW_EVENT_BUTTON; +import com.github.javafaker.Faker; +import com.opencsv.CSVParser; +import com.opencsv.CSVParserBuilder; +import com.opencsv.CSVReader; +import com.opencsv.CSVReaderBuilder; +import com.opencsv.exceptions.CsvException; +import cucumber.api.java8.En; +import java.io.FileReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import org.sormas.e2etests.entities.pojo.web.Event; +import org.sormas.e2etests.entities.services.EventService; +import org.sormas.e2etests.enums.DistrictsValues; +import org.sormas.e2etests.enums.RegionsValues; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.testng.asserts.SoftAssert; + @Slf4j public class CreateNewEventSteps implements En { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java index 67beedad457..4144e737de5 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java @@ -18,59 +18,6 @@ package org.sormas.e2etests.steps.web.application.events; -import com.github.javafaker.Faker; -import com.opencsv.CSVParser; -import com.opencsv.CSVParserBuilder; -import com.opencsv.CSVReader; -import com.opencsv.CSVReaderBuilder; -import com.opencsv.exceptions.CsvException; -import cucumber.api.java8.En; -import lombok.extern.slf4j.Slf4j; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.apache.poi.xwpf.usermodel.XWPFParagraph; -import org.openqa.selenium.By; -import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; -import org.sormas.e2etests.entities.pojo.web.Event; -import org.sormas.e2etests.entities.pojo.web.EventGroup; -import org.sormas.e2etests.entities.pojo.web.EventHandout; -import org.sormas.e2etests.entities.pojo.web.EventParticipant; -import org.sormas.e2etests.entities.pojo.web.Person; -import org.sormas.e2etests.entities.services.EventDocumentService; -import org.sormas.e2etests.entities.services.EventGroupService; -import org.sormas.e2etests.entities.services.EventParticipantService; -import org.sormas.e2etests.entities.services.EventService; -import org.sormas.e2etests.enums.DistrictsValues; -import org.sormas.e2etests.enums.GenderValues; -import org.sormas.e2etests.enums.RegionsValues; -import org.sormas.e2etests.envconfig.manager.RunningConfiguration; -import org.sormas.e2etests.helpers.AssertHelpers; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.helpers.files.FilesHelper; -import org.sormas.e2etests.pages.application.contacts.EditContactPage; -import org.sormas.e2etests.pages.application.events.EditEventPage; -import org.sormas.e2etests.state.ApiState; -import org.sormas.e2etests.steps.web.application.contacts.CreateNewContactSteps; -import org.sormas.e2etests.steps.web.application.contacts.EditContactSteps; -import org.sormas.e2etests.steps.web.application.persons.PersonDirectorySteps; -import org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps; -import org.testng.Assert; -import org.testng.asserts.SoftAssert; - -import javax.inject.Inject; -import java.io.FileInputStream; -import java.io.FileReader; -import java.io.IOException; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.time.format.TextStyle; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.Random; -import java.util.concurrent.TimeUnit; - import static org.sormas.e2etests.pages.application.actions.CreateNewActionPage.NEW_ACTION_POPUP; import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.ALL_RESULTS_CHECKBOX; import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CONFIRM_POPUP; @@ -263,6 +210,58 @@ import static org.sormas.e2etests.pages.application.samples.EditSamplePage.DELETE_SAMPLE_REASON_POPUP; import static org.sormas.e2etests.steps.BaseSteps.locale; +import com.github.javafaker.Faker; +import com.opencsv.CSVParser; +import com.opencsv.CSVParserBuilder; +import com.opencsv.CSVReader; +import com.opencsv.CSVReaderBuilder; +import com.opencsv.exceptions.CsvException; +import cucumber.api.java8.En; +import java.io.FileInputStream; +import java.io.FileReader; +import java.io.IOException; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.TextStyle; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.Random; +import java.util.concurrent.TimeUnit; +import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.apache.poi.xwpf.usermodel.XWPFParagraph; +import org.openqa.selenium.By; +import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; +import org.sormas.e2etests.entities.pojo.web.Event; +import org.sormas.e2etests.entities.pojo.web.EventGroup; +import org.sormas.e2etests.entities.pojo.web.EventHandout; +import org.sormas.e2etests.entities.pojo.web.EventParticipant; +import org.sormas.e2etests.entities.pojo.web.Person; +import org.sormas.e2etests.entities.services.EventDocumentService; +import org.sormas.e2etests.entities.services.EventGroupService; +import org.sormas.e2etests.entities.services.EventParticipantService; +import org.sormas.e2etests.entities.services.EventService; +import org.sormas.e2etests.enums.DistrictsValues; +import org.sormas.e2etests.enums.GenderValues; +import org.sormas.e2etests.enums.RegionsValues; +import org.sormas.e2etests.envconfig.manager.RunningConfiguration; +import org.sormas.e2etests.helpers.AssertHelpers; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.helpers.files.FilesHelper; +import org.sormas.e2etests.pages.application.contacts.EditContactPage; +import org.sormas.e2etests.pages.application.events.EditEventPage; +import org.sormas.e2etests.state.ApiState; +import org.sormas.e2etests.steps.web.application.contacts.CreateNewContactSteps; +import org.sormas.e2etests.steps.web.application.contacts.EditContactSteps; +import org.sormas.e2etests.steps.web.application.persons.PersonDirectorySteps; +import org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps; +import org.testng.Assert; +import org.testng.asserts.SoftAssert; + @Slf4j public class EditEventSteps implements En { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/CreateNewSampleSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/CreateNewSampleSteps.java index 663ce528009..0c360484e5e 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/CreateNewSampleSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/CreateNewSampleSteps.java @@ -18,34 +18,6 @@ package org.sormas.e2etests.steps.web.application.samples; -import com.github.javafaker.Faker; -import cucumber.api.java8.En; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; -import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; -import org.sormas.e2etests.entities.pojo.web.Sample; -import org.sormas.e2etests.entities.pojo.web.SampleAdditionalTest; -import org.sormas.e2etests.entities.services.SampleAdditionalTestService; -import org.sormas.e2etests.entities.services.SampleService; -import org.sormas.e2etests.enums.PathogenTestResults; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.state.ApiState; -import org.sormas.e2etests.steps.BaseSteps; -import org.testng.asserts.SoftAssert; - -import javax.inject.Inject; -import java.time.LocalDate; -import java.time.LocalTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.ACTION_CONFIRM_POPUP_BUTTON; import static org.sormas.e2etests.pages.application.cases.EditCasePage.SAMPLES_CARD_DATE_AND_TIME_OF_RESULT; import static org.sormas.e2etests.pages.application.cases.EditCasePage.SAMPLES_CARD_DATE_OF_COLLECTED_SAMPLE; @@ -147,6 +119,33 @@ import static org.sormas.e2etests.pages.application.samples.SamplesDirectoryPage.SAMPLE_RECEIVED_CHECKBOX; import static org.sormas.e2etests.pages.application.samples.SamplesDirectoryPage.SAMPLE_SHIPPED_CHECKBOX; +import com.github.javafaker.Faker; +import cucumber.api.java8.En; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import javax.inject.Inject; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; +import org.sormas.e2etests.entities.pojo.web.Sample; +import org.sormas.e2etests.entities.pojo.web.SampleAdditionalTest; +import org.sormas.e2etests.entities.services.SampleAdditionalTestService; +import org.sormas.e2etests.entities.services.SampleService; +import org.sormas.e2etests.enums.PathogenTestResults; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.state.ApiState; +import org.sormas.e2etests.steps.BaseSteps; +import org.testng.asserts.SoftAssert; + public class CreateNewSampleSteps implements En { public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("M/d/yyyy"); public static final DateTimeFormatter DATE_FORMATTER_DE = DateTimeFormatter.ofPattern("d.M.yyyy"); diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/EditSampleSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/EditSampleSteps.java index 1c4034e50f8..27a810a484c 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/EditSampleSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/EditSampleSteps.java @@ -18,22 +18,6 @@ package org.sormas.e2etests.steps.web.application.samples; -import cucumber.api.java8.En; -import org.openqa.selenium.By; -import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; -import org.sormas.e2etests.entities.pojo.web.Sample; -import org.sormas.e2etests.entities.services.SampleService; -import org.sormas.e2etests.entities.services.api.demis.DemisApiService; -import org.sormas.e2etests.envconfig.manager.RunningConfiguration; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.state.ApiState; -import org.testng.asserts.SoftAssert; - -import javax.inject.Inject; -import java.time.LocalDate; -import java.time.LocalTime; -import java.time.format.DateTimeFormatter; - import static org.sormas.e2etests.pages.application.samples.CreateNewSamplePage.SAVE_EDIT_SAMPLE_BUTTON; import static org.sormas.e2etests.pages.application.samples.EditSamplePage.ADDIITONAL_NEW_TEST_RESULT_BUTTON; import static org.sormas.e2etests.pages.application.samples.EditSamplePage.BACK_TO_CASE_DE_BUTTON; @@ -73,6 +57,21 @@ import static org.sormas.e2etests.pages.application.samples.SamplesDirectoryPage.SAMPLE_SEARCH_INPUT; import static org.sormas.e2etests.steps.BaseSteps.locale; +import cucumber.api.java8.En; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import javax.inject.Inject; +import org.openqa.selenium.By; +import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; +import org.sormas.e2etests.entities.pojo.web.Sample; +import org.sormas.e2etests.entities.services.SampleService; +import org.sormas.e2etests.entities.services.api.demis.DemisApiService; +import org.sormas.e2etests.envconfig.manager.RunningConfiguration; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.state.ApiState; +import org.testng.asserts.SoftAssert; + public class EditSampleSteps implements En { public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("M/d/yyyy"); public static final DateTimeFormatter DATE_FORMATTER_DE = @@ -316,22 +315,22 @@ public EditSampleSteps( Then( "I check that lab sample id match {string} specimen id from Demis message on Edit Sample page", (String specimen) -> { - switch (specimen) { - case "first": - softly.assertEquals( - webDriverHelpers.getValueFromWebElement(LAB_SAMPLE_ID_INPUT), - DemisApiService.specimenUUID, - "Sample id is incorrect"); - softly.assertAll(); - break; - case "second": - softly.assertEquals( - webDriverHelpers.getValueFromWebElement(LAB_SAMPLE_ID_INPUT), - DemisApiService.secondSpecimenUUID, - "Sample id is incorrect"); - softly.assertAll(); - break; - } + switch (specimen) { + case "first": + softly.assertEquals( + webDriverHelpers.getValueFromWebElement(LAB_SAMPLE_ID_INPUT), + DemisApiService.specimenUUID, + "Sample id is incorrect"); + softly.assertAll(); + break; + case "second": + softly.assertEquals( + webDriverHelpers.getValueFromWebElement(LAB_SAMPLE_ID_INPUT), + DemisApiService.secondSpecimenUUID, + "Sample id is incorrect"); + softly.assertAll(); + break; + } }); And( diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java index 32b794bd897..c665e9f7cbe 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java @@ -1,27 +1,5 @@ package org.sormas.e2etests.steps.web.application.survnet; -import cucumber.api.java8.En; -import lombok.extern.slf4j.Slf4j; -import org.jdom2.Attribute; -import org.jdom2.DataConversionException; -import org.jdom2.Document; -import org.jdom2.Element; -import org.jdom2.Namespace; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.helpers.parsers.XMLParser; -import org.sormas.e2etests.pages.application.NavBarPage; -import org.sormas.e2etests.steps.web.application.cases.CreateNewCaseSteps; -import org.sormas.e2etests.steps.web.application.events.EditEventSteps; -import org.sormas.e2etests.steps.web.application.persons.EditPersonSteps; -import org.testng.asserts.SoftAssert; - -import javax.inject.Inject; -import java.time.LocalDate; -import java.time.Period; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.List; - import static org.sormas.e2etests.helpers.SchemaValidator.XMLSchemaValidator.validateXMLSchema; import static org.sormas.e2etests.helpers.comparison.XMLComparison.compareXMLFiles; import static org.sormas.e2etests.helpers.comparison.XMLComparison.extractDiffNodes; @@ -41,6 +19,27 @@ import static org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps.randomVaccinationName; import static org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps.vaccination; +import cucumber.api.java8.En; +import java.time.LocalDate; +import java.time.Period; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; +import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import org.jdom2.Attribute; +import org.jdom2.DataConversionException; +import org.jdom2.Document; +import org.jdom2.Element; +import org.jdom2.Namespace; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.helpers.parsers.XMLParser; +import org.sormas.e2etests.pages.application.NavBarPage; +import org.sormas.e2etests.steps.web.application.cases.CreateNewCaseSteps; +import org.sormas.e2etests.steps.web.application.events.EditEventSteps; +import org.sormas.e2etests.steps.web.application.persons.EditPersonSteps; +import org.testng.asserts.SoftAssert; + @Slf4j public class SurvNetSteps implements En { @@ -710,71 +709,71 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { String mappedValue = null; switch (value) { - case"positive": - mappedValue = "20"; - break; - case"negative": - mappedValue = "0"; - break; - } + case "positive": + mappedValue = "20"; + break; + case "negative": + mappedValue = "0"; + break; + } switch (disease) { - case "diabetes": - softly.assertEquals( - getValueFromSpecificFieldByName(singleXmlFile, "Risk0005"), - mappedValue, - "Diabetes mapped value is incorrect!"); - softly.assertAll(); - break; - case "immunodeficiencyIncludingHiv": - softly.assertEquals( - getValueFromSpecificFieldByName(singleXmlFile, "Risk0008"), - mappedValue, - "Immunodeficiency mapped value is incorrect!"); - softly.assertAll(); - break; - case "chronicLiverDisease": - softly.assertEquals( - getValueFromSpecificFieldByName(singleXmlFile, "Risk0006"), - mappedValue, - "Liver disease mapped value is incorrect!"); - softly.assertAll(); - break; - case "malignancyChemotherapy": - softly.assertEquals( - getValueFromSpecificFieldByName(singleXmlFile, "Risk0011"), - mappedValue, - "Malignancy chemotherapy mapped value is incorrect!"); - softly.assertAll(); - break; - case "chronicPulmonaryDisease": - softly.assertEquals( - getValueFromSpecificFieldByName(singleXmlFile, "Risk0010"), - mappedValue, - "Chronic pulmonary disease mapped value is incorrect!"); - softly.assertAll(); - break; - case "chronicKidneyDisease": - softly.assertEquals( - getValueFromSpecificFieldByName(singleXmlFile, "Risk0009"), - mappedValue, - "Chronic kidney disease mapped value is incorrect!"); - softly.assertAll(); - break; - case "chronicNeurologicCondition": - softly.assertEquals( - getValueFromSpecificFieldByName(singleXmlFile, "Risk0007"), - mappedValue, - "Chronic neurologic condition mapped value is incorrect!"); - softly.assertAll(); - break; - case "cardiovascularDiseaseIncludingHypertension": - softly.assertEquals( - getValueFromSpecificFieldByName(singleXmlFile, "Risk0004"), - mappedValue, - "Cardiovascular disease mapped value is incorrect!"); - softly.assertAll(); - break; + case "diabetes": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0005"), + mappedValue, + "Diabetes mapped value is incorrect!"); + softly.assertAll(); + break; + case "immunodeficiencyIncludingHiv": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0008"), + mappedValue, + "Immunodeficiency mapped value is incorrect!"); + softly.assertAll(); + break; + case "chronicLiverDisease": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0006"), + mappedValue, + "Liver disease mapped value is incorrect!"); + softly.assertAll(); + break; + case "malignancyChemotherapy": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0011"), + mappedValue, + "Malignancy chemotherapy mapped value is incorrect!"); + softly.assertAll(); + break; + case "chronicPulmonaryDisease": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0010"), + mappedValue, + "Chronic pulmonary disease mapped value is incorrect!"); + softly.assertAll(); + break; + case "chronicKidneyDisease": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0009"), + mappedValue, + "Chronic kidney disease mapped value is incorrect!"); + softly.assertAll(); + break; + case "chronicNeurologicCondition": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0007"), + mappedValue, + "Chronic neurologic condition mapped value is incorrect!"); + softly.assertAll(); + break; + case "cardiovascularDiseaseIncludingHypertension": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0004"), + mappedValue, + "Cardiovascular disease mapped value is incorrect!"); + softly.assertAll(); + break; } }); @@ -784,20 +783,19 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { switch (infectionOption) { case "Ambulant": softly.assertEquals( - getValueFromSpecificFieldByName(singleXmlFile, "P112Setting"), - "1000", - "Mapped value for Ambulance is incorrect"); + getValueFromSpecificFieldByName(singleXmlFile, "P112Setting"), + "1000", + "Mapped value for Ambulance is incorrect"); softly.assertAll(); break; case "Stationär": softly.assertEquals( - getValueFromSpecificFieldByName(singleXmlFile, "P112Setting"), - "2000", - "Mapped value for Stationär is incorrect "); + getValueFromSpecificFieldByName(singleXmlFile, "P112Setting"), + "2000", + "Mapped value for Stationär is incorrect "); softly.assertAll(); break; } - }); } diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedCases.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedCases.feature index f26c82f69d9..28808c85c5c 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedCases.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedCases.feature @@ -11,9 +11,9 @@ Feature: Sharing cases between environments tests Then I navigate to the last created case via the url And I check if handover card contains "Dieser Fall ist nicht geteilt" information And I collect uuid of the case - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" - And I click to hand over the ownership of the case in Share popup + And I click to hand over the ownership in Share popup And I fill comment in share popup with "shared to be deleted after" Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment @@ -32,7 +32,7 @@ Feature: Sharing cases between environments tests Then I click on the APPLY FILTERS button And I select first created case for person from Cases list Then Total number of read only fields should be 13 - And I check if handover card contains "Eigentümer: LK Fulda" information + And I check if handover card contains shared with "s2s_2" information And I check if handover card contains "Geteilt von: S2S USER" information And I check if handover card contains "shared to be deleted after" information Then I navigate to "s2s_2" environment @@ -42,7 +42,7 @@ Feature: Sharing cases between environments tests Then I click on the APPLY FILTERS button And I select first created case for person from Cases list Then I check if editable fields are enabled for the case in view - And I check if handover card contains "Gesendet von LK Barnim" information + And I check if handover card contains shared with "s2s_1" information And I check if handover card contains "Geteilt von: S2S User" information And I check if handover card contains "shared to be deleted after" information @@ -56,9 +56,9 @@ Feature: Sharing cases between environments tests And I collect uuid of the case Then I click on the Archive case button and confirm popup And I click on save button from Edit Case page - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" - And I click to hand over the ownership of the case in Share popup + And I click to hand over the ownership in Share popup And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab @@ -89,7 +89,7 @@ Feature: Sharing cases between environments tests And I select the German words for Rapid Antigen Detection Test as Type of Test in the Create New Sample popup And I save the created sample with pathogen test And I open the last created Case via API - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string And I click to share samples of the case in Share popup @@ -132,7 +132,7 @@ Feature: Sharing cases between environments tests And I select the German words for Rapid Antigen Detection Test as Type of Test in the Create New Sample popup And I save the created sample with pathogen test And I open the last created Case via API - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish @@ -171,7 +171,7 @@ Feature: Sharing cases between environments tests And I select the German words for Rapid Antigen Detection Test as Type of Test in the Create New Sample popup And I save the created sample with pathogen test And I open the last created Case via API - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish @@ -202,9 +202,9 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Given I log in as a S2S And I open the last created Case via API - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" - And I click to hand over the ownership of the case in Share popup + And I click to hand over the ownership in Share popup And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish And I click NEW VACCINATION button for DE @@ -246,9 +246,9 @@ Feature: Sharing cases between environments tests And I select the German words for Rapid Antigen Detection Test as Type of Test in the Create New Sample popup And I save the created sample with pathogen test And I open the last created Case via API - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" - And I click to hand over the ownership of the case in Share popup + And I click to hand over the ownership in Share popup And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab @@ -292,9 +292,9 @@ Feature: Sharing cases between environments tests And I select the German words for Rapid Antigen Detection Test as Type of Test in the Create New Sample popup And I save the created sample with pathogen test And I open the last created Case via API - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" - And I click to hand over the ownership of the case in Share popup + And I click to hand over the ownership in Share popup And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab @@ -338,9 +338,9 @@ Feature: Sharing cases between environments tests And I select the German words for Rapid Antigen Detection Test as Type of Test in the Create New Sample popup And I save the created sample with pathogen test And I open the last created Case via API - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" - And I click to hand over the ownership of the case in Share popup + And I click to hand over the ownership in Share popup And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab @@ -378,7 +378,7 @@ Feature: Sharing cases between environments tests Then I click on new contact button from Case Contacts tab And I create a new basic contact to from Cases Contacts tab for DE And I open the last created Case via API - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish @@ -392,7 +392,7 @@ Feature: Sharing cases between environments tests And I click on New Sample in German And I create a new Sample with only required fields for DE version And I click on save sample button - And I click on share contact button + And I click on share button And I select organization to share with "s2s_2" And I click to share samples of the case in Share popup And I fill comment in share popup for case with random string @@ -419,7 +419,7 @@ Feature: Sharing cases between environments tests And I click on New Sample in German And I create a new Sample with only required fields for DE version And I click on save sample button - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I click to share samples of the case in Share popup And I fill comment in share popup for case with random string @@ -449,9 +449,9 @@ Feature: Sharing cases between environments tests Then I create a new case with specific person name and "Hessen" region and "LK Fulda" district for DE version Then I click on save button in the case popup Then I back to tab number 1 - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" - And I click to hand over the ownership of the case in Share popup + And I click to hand over the ownership in Share popup And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I back to tab number 2 @@ -480,9 +480,9 @@ Feature: Sharing cases between environments tests Then I create a new case with specific person name and "Hessen" region and "LK Fulda" district for DE version Then I click on save button in the case popup Then I back to tab number 1 - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" - And I click to hand over the ownership of the case in Share popup + And I click to hand over the ownership in Share popup And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I back to tab number 2 @@ -511,7 +511,7 @@ Feature: Sharing cases between environments tests Then I create a new case with mandatory data with person name and "Baden-Württemberg" region and "LK Alb-Donau-Kreis" district for DE version Then I click on save button in the case popup Then I back to tab number 1 - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish @@ -552,7 +552,7 @@ Feature: Sharing cases between environments tests And I click on the Cases button from navbar And I search the case by last created person via Demis message Then I click on the first Case ID from Case Directory - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_3" And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish @@ -583,28 +583,28 @@ Feature: Sharing cases between environments tests Then I click on new contact button from Case Contacts tab And I create a new basic contact to from Cases Contacts tab for DE And I open the last created Case via API - Then I click on share case button - And I click to hand over the ownership of the case in Share popup + Then I click on share button + And I click to hand over the ownership in Share popup And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish And I open the last created Case via API - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I check if share warning is displayed And I open the last created Case via API - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_3" - And I click to hand over the ownership of the case in Share popup + And I click to hand over the ownership in Share popup And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup And I check if popup with error with handover header displays And I open the last created Case via API And I click on revoke share button Then I click on Ja button in Revoke case popup - Then I click on share case button - And I click to hand over the ownership of the case in Share popup + Then I click on share button + And I click to hand over the ownership in Share popup And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish @@ -625,19 +625,19 @@ Feature: Sharing cases between environments tests Then I click on new contact button from Case Contacts tab And I create a new basic contact to from Cases Contacts tab for DE And I open the last created Case via API - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string And I click to share samples of the case in Share popup And I click to share reports of the case in Share popup Then I click on share button in s2s share popup and wait for share to finish And I open the last created Case via API - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I check if share warning is displayed And I open the last created Case via API - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_3" And I fill comment in share popup with "shared with automated test" And I click to share samples of the case in Share popup @@ -646,7 +646,7 @@ Feature: Sharing cases between environments tests And I open the last created Case via API And I click on revoke share button Then I click on Ja button in Revoke case popup - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish @@ -655,10 +655,10 @@ Feature: Sharing cases between environments tests And I click on the Shares button from navbar And I click on "accept" shared case button with copied case description Then I back to tab number 1 - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string - And I click to hand over the ownership of the case in Share popup + And I click to hand over the ownership in Share popup Then I click on share button in s2s share popup and wait for share to finish @tmsLink=SORDEV-11838 @env_s2s_1 @@ -673,19 +673,19 @@ Feature: Sharing cases between environments tests Then I click on new contact button from Case Contacts tab And I create a new basic contact to from Cases Contacts tab for DE And I open the last created Case via API - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string - And I click to hand over the ownership of the case in Share popup + And I click to hand over the ownership in Share popup Then I click on share button in s2s share popup and wait for share to finish Then I navigate to Contacts tab in Edit case page And I open the first contact from contacts list - Then I click on share contact button - And I click to hand over the ownership of the case in Share popup + Then I click on share button + And I click to hand over the ownership in Share popup And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish - Then I click on share contact button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I check if share warning is displayed @@ -694,10 +694,10 @@ Feature: Sharing cases between environments tests And I open the first contact from contacts list And I click on revoke share button Then I click on Ja button in Revoke case popup - Then I click on share contact button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup for contact with random string - And I click to hand over the ownership of the case in Share popup + And I click to hand over the ownership in Share popup Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab Given I log in as a S2S @@ -716,7 +716,7 @@ Feature: Sharing cases between environments tests Then I click on new contact button from Case Contacts tab And I create a new basic contact to from Cases Contacts tab for DE And I open the last created Case via API - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string And I click to share samples of the case in Share popup @@ -724,12 +724,12 @@ Feature: Sharing cases between environments tests Then I click on share button in s2s share popup and wait for share to finish Then I navigate to Contacts tab in Edit case page And I open the first contact from contacts list - Then I click on share contact button + Then I click on share button And I click to share samples of the case in Share popup And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish - Then I click on share contact button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I check if share warning is displayed @@ -738,7 +738,7 @@ Feature: Sharing cases between environments tests And I open the first contact from contacts list And I click on revoke share button Then I click on Ja button in Revoke case popup - Then I click on share contact button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup for contact with random string Then I click on share button in s2s share popup and wait for share to finish @@ -747,10 +747,10 @@ Feature: Sharing cases between environments tests And I click on the Shares button from navbar And I click on "accept" shared contact button with copied contact description Then I back to tab number 1 - Then I click on share contact button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup for contact with random string - And I click to hand over the ownership of the case in Share popup + And I click to hand over the ownership in Share popup Then I click on share button in s2s share popup and wait for share to finish @tmsLink=SORDEV-12447 @env_s2s_1 @@ -765,7 +765,7 @@ Feature: Sharing cases between environments tests Then I click on new contact button from Case Contacts tab And I create a new basic contact to from Cases Contacts tab for DE And I open the last created Case via API - Then I click on share case button + Then I click on share button And I check that share associated contacts checkbox is not visible in Share form for DE And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string @@ -788,7 +788,7 @@ Feature: Sharing cases between environments tests Then I click on new contact button from Case Contacts tab And I create a new basic contact to from Cases Contacts tab for DE And I open the last created Case via API - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish @@ -799,7 +799,7 @@ Feature: Sharing cases between environments tests Then I back to tab number 1 When I open the Case Contacts tab And I click on the first Contact ID from Contacts Directory in Contacts in Case - And I click on share contact button + And I click on share button And I check that share associated contacts checkbox is not visible in Share form for DE And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string @@ -818,7 +818,7 @@ Feature: Sharing cases between environments tests Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish @@ -840,7 +840,7 @@ Feature: Sharing cases between environments tests Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish @@ -862,7 +862,7 @@ Feature: Sharing cases between environments tests Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish @@ -873,7 +873,7 @@ Feature: Sharing cases between environments tests Then I fill comment field in Reject share request popup and click confirm Then I navigate to "s2s_1" environment Then I navigate to the last created case via the url - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish @@ -890,8 +890,8 @@ Feature: Sharing cases between environments tests Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case - Then I click on share case button - And I click to hand over the ownership of the case in Share popup + Then I click on share button + And I click to hand over the ownership in Share popup And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish @@ -901,7 +901,7 @@ Feature: Sharing cases between environments tests And I click on "accept" shared case button with copied case description Then I navigate to "s2s_1" environment Then I navigate to the last created case via the url without check if uuid is enabled - And I check if share case button in Edit Case is unavailable + And I check if share button is unavailable @tmsLink=SORDEV-12081 @env_s2s_1 Scenario: Accept Reject Special Cases [5] @@ -912,8 +912,8 @@ Feature: Sharing cases between environments tests Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case - Then I click on share case button - And I click to hand over the ownership of the case in Share popup + Then I click on share button + And I click to hand over the ownership in Share popup And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish @@ -936,8 +936,8 @@ Feature: Sharing cases between environments tests Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case - Then I click on share case button - And I click to hand over the ownership of the case in Share popup + Then I click on share button + And I click to hand over the ownership in Share popup And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish @@ -973,8 +973,8 @@ Feature: Sharing cases between environments tests And I click on the Cases button from navbar And I search the case by last created person via Demis message Then I click on the first Case ID from Case Directory - Then I click on share case button - And I click to hand over the ownership of the case in Share popup + Then I click on share button + And I click to hand over the ownership in Share popup And I select organization to share with "s2s_3" And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish @@ -1002,8 +1002,8 @@ Feature: Sharing cases between environments tests Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case - Then I click on share case button - And I click to hand over the ownership of the case in Share popup + Then I click on share button + And I click to hand over the ownership in Share popup And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish @@ -1042,8 +1042,8 @@ Feature: Sharing cases between environments tests Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case - Then I click on share case button - And I click to hand over the ownership of the case in Share popup + Then I click on share button + And I click to hand over the ownership in Share popup And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish @@ -1073,7 +1073,7 @@ Feature: Sharing cases between environments tests Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish @@ -1103,7 +1103,7 @@ Feature: Sharing cases between environments tests Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish @@ -1135,7 +1135,7 @@ Feature: Sharing cases between environments tests And API: I check that POST call status code is 200 Given I log in as a S2S Then I navigate to the last created case via the url - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish @@ -1157,7 +1157,7 @@ Feature: Sharing cases between environments tests Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish @@ -1176,7 +1176,7 @@ Feature: Sharing cases between environments tests Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedContacts.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedContacts.feature index 54e6e896a37..b9188e380f9 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedContacts.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedContacts.feature @@ -13,26 +13,26 @@ Feature: Sharing contacts between environments tests And I fill a new contact form for DE version with mandatory data with "Baden-Württemberg" as a region and "LK Alb-Donau-Kreis" as a disctrict And I click on SAVE new contact button And I copy url of current contact - And I click on share contact button + And I click on share button Then I check if popup with "Kontakt kann nicht geteilt werden" title appears And I click on okay button And I click on the CHOOSE SOURCE CASE button from CONTACT page Then I search for the last case uuid created via Api in the CHOOSE SOURCE Contact window And I open the first found result in the CHOOSE SOURCE window for DE version Then I click SAVE button on Edit Contact Page - And I click on share contact button + And I click on share button And I select organization to share with "s2s_2" Then I check if warning information with related to the associated case not being shared appears in share contact popup And I click on discard button Then I open the Case Contacts tab And I navigate to case tab - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to Contacts tab in Edit case page And I open the first contact from contacts list - And I click on share contact button + And I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup for contact with random string Then I click on share button in s2s share popup and wait for share to finish @@ -66,7 +66,7 @@ Feature: Sharing contacts between environments tests And I save a new case And I collect uuid of the case Then I back to contact by url - And I click on share contact button + And I click on share button Then I check if popup with "Kontakt kann nicht geteilt werden" header appears And I click on okay button Then I click on the CHOOSE SOURCE CASE button from CONTACT page @@ -75,16 +75,16 @@ Feature: Sharing contacts between environments tests Then I click SAVE button on Edit Contact Page Then I open the Case Contacts tab Then I navigate to case tab - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" - And I click to hand over the ownership of the case in Share popup + And I click to hand over the ownership in Share popup And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I open the Case Contacts tab And I click on the first Contact ID from Contacts Directory in Contacts in Case - And I click on share contact button + And I click on share button And I select organization to share with "s2s_2" - And I click to hand over the ownership of the contact in Share popup + And I click to hand over the ownership in Share popup And I fill comment in share popup for contact with random string Then I click on share button in s2s share popup And I check if popup with error with handover header displays @@ -100,7 +100,7 @@ Feature: Sharing contacts between environments tests Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish @@ -110,8 +110,8 @@ Feature: Sharing contacts between environments tests Then I accept first entity from table in Shares Page Then I navigate to "s2s_1" environment Then I open the last created contact via API - Then I click on share contact button - And I click to hand over the ownership of the contact in Share popup + Then I click on share button + And I click to hand over the ownership in Share popup And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish @@ -145,7 +145,7 @@ Feature: Sharing contacts between environments tests Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish @@ -155,8 +155,8 @@ Feature: Sharing contacts between environments tests Then I accept first entity from table in Shares Page Then I navigate to "s2s_1" environment Then I open the last created contact via API - Then I click on share contact button - And I click to hand over the ownership of the contact in Share popup + Then I click on share button + And I click to hand over the ownership in Share popup And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish @@ -187,7 +187,7 @@ Feature: Sharing contacts between environments tests Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish @@ -197,7 +197,7 @@ Feature: Sharing contacts between environments tests Then I accept first entity from table in Shares Page Then I navigate to "s2s_1" environment Then I open the last created contact via API - Then I click on share contact button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish @@ -229,7 +229,7 @@ Feature: Sharing contacts between environments tests Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish @@ -239,7 +239,7 @@ Feature: Sharing contacts between environments tests Then I accept first entity from table in Shares Page Then I navigate to "s2s_1" environment Then I open the last created contact via API - Then I click on share contact button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish @@ -271,7 +271,7 @@ Feature: Sharing contacts between environments tests And API: I check that POST call status code is 200 Given I log in as a S2S Then I navigate to the last created case via the url - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish @@ -281,9 +281,9 @@ Feature: Sharing contacts between environments tests Then I accept first entity from table in Shares Page Then I navigate to "s2s_1" environment Then I open the last created contact via API - Then I click on share contact button + Then I click on share button And I select organization to share with "s2s_2" - And I click to hand over the ownership of the contact in Share popup + And I click to hand over the ownership in Share popup And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish Then I click on Delete button from contact @@ -305,9 +305,9 @@ Feature: Sharing contacts between environments tests Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" - And I click to hand over the ownership of the case in Share popup + And I click to hand over the ownership in Share popup And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment @@ -316,8 +316,8 @@ Feature: Sharing contacts between environments tests Then I accept first entity from table in Shares Page Then I navigate to "s2s_1" environment Then I open the last created contact via API - Then I click on share contact button - And I click to hand over the ownership of the contact in Share popup + Then I click on share button + And I click to hand over the ownership in Share popup And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish @@ -353,9 +353,9 @@ Feature: Sharing contacts between environments tests Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" - And I click to hand over the ownership of the case in Share popup + And I click to hand over the ownership in Share popup And I fill comment in share popup for case with random string Then I click on share button in s2s share popup and wait for share to finish Then I navigate to "s2s_2" environment in new driver tab @@ -366,8 +366,8 @@ Feature: Sharing contacts between environments tests Then I back to tab number 1 Then I open the last created contact via API from "s2s_1" And I collect uuid of the contact - Then I click on share contact button - And I click to hand over the ownership of the contact in Share popup + Then I click on share button + And I click to hand over the ownership in Share popup And I select organization to share with "s2s_2" And I fill comment in share popup for contact with random string Then I click on share button in s2s share popup and wait for share to finish diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedPersons.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedPersons.feature index 84409aee27a..6176117b813 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedPersons.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedPersons.feature @@ -12,8 +12,8 @@ Feature: Sharing persons between environments tests Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case - Then I click on share case button - And I click to hand over the ownership of the contact in Share popup + Then I click on share button + And I click to hand over the ownership in Share popup And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish @@ -24,8 +24,8 @@ Feature: Sharing persons between environments tests When I back to tab number 1 Then I navigate to "s2s_1" environment Then I open the last created contact via API - And I click on share contact button - And I click to hand over the ownership of the contact in Share popup + And I click on share button + And I click to hand over the ownership in Share popup And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish @@ -53,8 +53,8 @@ Feature: Sharing persons between environments tests Given I log in as a S2S Then I navigate to the last created case via the url And I collect uuid of the case - Then I click on share case button - And I click to hand over the ownership of the contact in Share popup + Then I click on share button + And I click to hand over the ownership in Share popup And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish @@ -81,7 +81,7 @@ Feature: Sharing persons between environments tests And I fill new case data for duplicates merge with for one person data for DE And I save a new case And I collect uuid of the case - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish @@ -140,7 +140,7 @@ Feature: Sharing persons between environments tests And I open the first found result in the CHOOSE SOURCE window for DE version Then I click SAVE button on Edit Contact Page Then I navigate to the last created case via the url - Then I click on share case button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish @@ -151,7 +151,7 @@ Feature: Sharing persons between environments tests When I back to tab number 1 And I navigate to Contacts tab in Edit case page And I open a contact using the collected contact UUID - Then I click on share contact button + Then I click on share button And I select organization to share with "s2s_2" And I fill comment in share popup with "shared with automated test" Then I click on share button in s2s share popup and wait for share to finish From 10e2c66cb2338f2e70a90a808e6f485f66316a09 Mon Sep 17 00:00:00 2001 From: Levente Gal <62599627+leventegal-she@users.noreply.github.com> Date: Fri, 28 Jul 2023 10:17:06 +0300 Subject: [PATCH 130/174] Feature 12028 disease variant bulk edit no scripts (#12358) * #12028 Add the disease variant to the edit forms of cases in Bulk action * #12028 Add the disease variant to the edit forms of cases in Bulk action - added tests --------- Co-authored-by: Levente Gal --- .../sormas/api/caze/CaseBulkEditData.java | 23 ++- .../de/symeda/sormas/api/caze/CaseFacade.java | 2 + .../CustomizableEnumFacade.java | 13 ++ .../de/symeda/sormas/api/i18n/Captions.java | 1 + .../src/main/resources/captions.properties | 1 + .../sormas/backend/caze/CaseFacadeEjb.java | 30 +++- .../CustomizableEnumFacadeEjb.java | 6 + .../sormas/backend/TestDataCreator.java | 27 +-- .../backend/caze/CaseFacadeEjbTest.java | 66 ++++++++ .../sormas/ui/caze/BulkCaseDataForm.java | 155 ++++++++++++++---- .../symeda/sormas/ui/caze/CaseController.java | 3 + 11 files changed, 276 insertions(+), 51 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseBulkEditData.java b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseBulkEditData.java index db5a48322aa..fe061a6d056 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseBulkEditData.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseBulkEditData.java @@ -42,8 +42,9 @@ public class CaseBulkEditData extends EntityDto { private static final long serialVersionUID = -4670022133882295863L; public static final String DISEASE = "disease"; - public static final String DISEASE_VARIANT = "diseaseVariant"; public static final String DISEASE_DETAILS = "diseaseDetails"; + public static final String DISEASE_VARIANT = "diseaseVariant"; + public static final String DISEASE_VARIANT_DETAILS = "diseaseVariantDetails"; public static final String PLAGUE_TYPE = "plagueType"; public static final String DENGUE_FEVER_TYPE = "dengueFeverType"; public static final String RABIES_TYPE = "rabiesType"; @@ -60,9 +61,11 @@ public class CaseBulkEditData extends EntityDto { public static final String DONT_SHARE_WITH_REPORTING_TOOL = "dontShareWithReportingTool"; private Disease disease; - private DiseaseVariant diseaseVariant; @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String diseaseDetails; + private DiseaseVariant diseaseVariant; + @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) + private String diseaseVariantDetails; private PlagueType plagueType; private DengueFeverType dengueFeverType; private RabiesType rabiesType; @@ -87,6 +90,14 @@ public void setDisease(Disease disease) { this.disease = disease; } + public String getDiseaseDetails() { + return diseaseDetails; + } + + public void setDiseaseDetails(String diseaseDetails) { + this.diseaseDetails = diseaseDetails; + } + public DiseaseVariant getDiseaseVariant() { return diseaseVariant; } @@ -95,12 +106,12 @@ public void setDiseaseVariant(DiseaseVariant diseaseVariant) { this.diseaseVariant = diseaseVariant; } - public String getDiseaseDetails() { - return diseaseDetails; + public String getDiseaseVariantDetails() { + return diseaseVariantDetails; } - public void setDiseaseDetails(String diseaseDetails) { - this.diseaseDetails = diseaseDetails; + public void setDiseaseVariantDetails(String diseaseVariantDetails) { + this.diseaseVariantDetails = diseaseVariantDetails; } public PlagueType getPlagueType() { diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseFacade.java index f7aceb299db..883bdd4e629 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseFacade.java @@ -180,6 +180,7 @@ Integer saveBulkCase( List caseUuidList, @Valid CaseBulkEditData updatedCaseBulkEditData, boolean diseaseChange, + boolean diseaseVariantChange, boolean classificationChange, boolean investigationStatusChange, boolean outcomeChange, @@ -189,6 +190,7 @@ Integer saveBulkEditWithFacilities( List caseUuidList, @Valid CaseBulkEditData updatedCaseBulkEditData, boolean diseaseChange, + boolean diseaseVariantChange, boolean classificationChange, boolean investigationStatusChange, boolean outcomeChange, diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/customizableenum/CustomizableEnumFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/customizableenum/CustomizableEnumFacade.java index ec95d46de45..fbd8584d071 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/customizableenum/CustomizableEnumFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/customizableenum/CustomizableEnumFacade.java @@ -63,6 +63,19 @@ public interface CustomizableEnumFacade { */ T getEnumValue(CustomizableEnumType type, String value, Disease disease) throws CustomEnumNotFoundException; + /** + * Checks if the specified enum value exists for the specified type and disease. + * + * @param type + * The type for which to retrieve the enum value + * @param value + * The values to search for + * @param disease + * The disease for which to retrieve the enum values. If null, all enum values that are disease-independent are retrieved + * @return true if the enum value exists + */ + boolean existsEnumValue(CustomizableEnumType type, String value, Disease disease); + /** * Retrieves the cached contents of all enum value instances of the specified type. The results are already * internationalized based on the user's language, or the server language as a fallback. If the enum values for the diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java index 0bf053ebd65..6e6e8b32d0b 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java @@ -220,6 +220,7 @@ public interface Captions { String bulkContactOfficer = "bulkContactOfficer"; String bulkDelete = "bulkDelete"; String bulkDisease = "bulkDisease"; + String bulkDiseaseVariant = "bulkDiseaseVariant"; String bulkEdit = "bulkEdit"; String bulkEditAssignee = "bulkEditAssignee"; String bulkEventInvestigationStatus = "bulkEventInvestigationStatus"; diff --git a/sormas-api/src/main/resources/captions.properties b/sormas-api/src/main/resources/captions.properties index f8c88cb4401..a5ec3244c56 100644 --- a/sormas-api/src/main/resources/captions.properties +++ b/sormas-api/src/main/resources/captions.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseFacadeEjb.java index 17a058182b0..b920fe34058 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseFacadeEjb.java @@ -134,7 +134,9 @@ import de.symeda.sormas.api.contact.ContactCriteria; import de.symeda.sormas.api.contact.ContactDto; import de.symeda.sormas.api.contact.ContactReferenceDto; +import de.symeda.sormas.api.customizableenum.CustomizableEnumType; import de.symeda.sormas.api.deletionconfiguration.DeletionReference; +import de.symeda.sormas.api.disease.DiseaseVariant; import de.symeda.sormas.api.document.DocumentRelatedEntityType; import de.symeda.sormas.api.epidata.EpiDataDto; import de.symeda.sormas.api.epidata.EpiDataHelper; @@ -247,6 +249,7 @@ import de.symeda.sormas.backend.contact.ContactFacadeEjb.ContactFacadeEjbLocal; import de.symeda.sormas.backend.contact.ContactService; import de.symeda.sormas.backend.contact.VisitSummaryExportDetails; +import de.symeda.sormas.backend.customizableenum.CustomizableEnumFacadeEjb.CustomizableEnumFacadeEjbLocal; import de.symeda.sormas.backend.disease.DiseaseConfigurationFacadeEjb.DiseaseConfigurationFacadeEjbLocal; import de.symeda.sormas.backend.document.Document; import de.symeda.sormas.backend.document.DocumentService; @@ -491,6 +494,8 @@ public class CaseFacadeEjb extends AbstractCoreFacadeEjb save(@Valid @NotNull CoreAndPersonDto caseUuidList, @Valid CaseBulkEditData updatedCaseBulkEditData, boolean diseaseChange, + boolean diseaseVariantChange, boolean classificationChange, boolean investigationStatusChange, boolean outcomeChange, @@ -1537,6 +1544,7 @@ public Integer saveBulkCase( updatedCaseBulkEditData, caze, diseaseChange, + diseaseVariantChange, classificationChange, investigationStatusChange, outcomeChange, @@ -1548,12 +1556,14 @@ public Integer saveBulkCase( return changedCases; } + @Override @RightsAllowed({ UserRight._CASE_EDIT }) public Integer saveBulkEditWithFacilities( List caseUuidList, @Valid CaseBulkEditData updatedCaseBulkEditData, boolean diseaseChange, + boolean diseaseVariantChange, boolean classificationChange, boolean investigationStatusChange, boolean outcomeChange, @@ -1576,6 +1586,7 @@ public Integer saveBulkEditWithFacilities( updatedCaseBulkEditData, caze, diseaseChange, + diseaseVariantChange, classificationChange, investigationStatusChange, outcomeChange, @@ -1600,14 +1611,29 @@ private void updateCaseWithBulkData( CaseBulkEditData updatedCaseBulkEditData, Case existingCase, boolean diseaseChange, + boolean diseaseVariantChange, boolean classificationChange, boolean investigationStatusChange, boolean outcomeChange, boolean surveillanceOfficerChange) { if (diseaseChange) { - existingCase.setDisease(updatedCaseBulkEditData.getDisease()); - existingCase.setDiseaseVariant(updatedCaseBulkEditData.getDiseaseVariant()); + Disease newDisease = updatedCaseBulkEditData.getDisease(); + existingCase.setDisease(newDisease); + + if (!diseaseVariantChange + && existingCase.getDiseaseVariant() != null + && !customizableEnumFacade + .existsEnumValue(CustomizableEnumType.DISEASE_VARIANT, existingCase.getDiseaseVariant().getValue(), newDisease)) { + existingCase.setDiseaseVariant(null); + existingCase.setDiseaseVariantDetails(null); + } else if (diseaseVariantChange) { + DiseaseVariant diseaseVariant = updatedCaseBulkEditData.getDiseaseVariant(); + existingCase.setDiseaseVariant(diseaseVariant); + + existingCase.setDiseaseVariantDetails(diseaseVariant == null ? null : updatedCaseBulkEditData.getDiseaseVariantDetails()); + } + existingCase.setDiseaseDetails(updatedCaseBulkEditData.getDiseaseDetails()); existingCase.setPlagueType(updatedCaseBulkEditData.getPlagueType()); existingCase.setDengueFeverType(updatedCaseBulkEditData.getDengueFeverType()); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/customizableenum/CustomizableEnumFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/customizableenum/CustomizableEnumFacadeEjb.java index a43c7c6642e..f5575b7fb67 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/customizableenum/CustomizableEnumFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/customizableenum/CustomizableEnumFacadeEjb.java @@ -135,6 +135,12 @@ public T getEnumValue(CustomizableEnumType type, St "Invalid enum value " + value + " for customizable enum type " + type + " and disease " + disease)); } + @Lock(LockType.READ) + @Override + public boolean existsEnumValue(CustomizableEnumType type, String value, Disease disease) { + return getEnumValues(type, disease).stream().anyMatch(e -> e.getValue().equals(value)); + } + /** * @return Entries are currently not returned in any specific order */ diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/TestDataCreator.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/TestDataCreator.java index 6d17ea4d19c..42511d2ca54 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/TestDataCreator.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/TestDataCreator.java @@ -17,6 +17,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -57,7 +58,9 @@ import de.symeda.sormas.api.clinicalcourse.HealthConditionsDto; import de.symeda.sormas.api.contact.ContactDto; import de.symeda.sormas.api.contact.ContactReferenceDto; +import de.symeda.sormas.api.customizableenum.CustomizableEnumType; import de.symeda.sormas.api.disease.DiseaseConfigurationDto; +import de.symeda.sormas.api.disease.DiseaseVariant; import de.symeda.sormas.api.document.DocumentDto; import de.symeda.sormas.api.document.DocumentRelatedEntityType; import de.symeda.sormas.api.environment.EnvironmentDto; @@ -136,6 +139,7 @@ import de.symeda.sormas.api.vaccination.VaccinationDto; import de.symeda.sormas.api.visit.VisitDto; import de.symeda.sormas.api.visit.VisitStatus; +import de.symeda.sormas.backend.customizableenum.CustomizableEnumValue; import de.symeda.sormas.backend.disease.DiseaseConfigurationFacadeEjb.DiseaseConfigurationFacadeEjbLocal; import de.symeda.sormas.backend.infrastructure.community.Community; import de.symeda.sormas.backend.infrastructure.continent.Continent; @@ -2076,17 +2080,18 @@ public TestReportDto createTestReport(SampleReportDto sampleReport) { return testReport; } -// public DiseaseVariant createDiseaseVariant(String name, Disease disease) { -// -// DiseaseVariant diseaseVariant = new DiseaseVariant(); -// diseaseVariant.setUuid(DataHelper.createUuid()); -// diseaseVariant.setName(name); -// diseaseVariant.setDisease(disease); -// -// beanTest.getDiseaseVariantService().persist(diseaseVariant); -// -// return diseaseVariant; -// } + public DiseaseVariant createDiseaseVariant(String name, Disease disease) { + + CustomizableEnumValue diseaseVariant = new CustomizableEnumValue(); + diseaseVariant.setDataType(CustomizableEnumType.DISEASE_VARIANT); + diseaseVariant.setValue("BF.1.2"); + diseaseVariant.setDiseases(Collections.singletonList(disease)); + diseaseVariant.setCaption(name + " variant"); + + beanTest.getCustomizableEnumValueService().ensurePersisted(diseaseVariant); + + return beanTest.getCustomizableEnumFacade().getEnumValue(CustomizableEnumType.DISEASE_VARIANT, name); + } public ExternalShareInfo createExternalShareInfo( CaseReferenceDto caze, diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbTest.java index cb37ede80d1..af4434a08ae 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbTest.java @@ -23,6 +23,7 @@ import static org.hamcrest.Matchers.isEmptyOrNullString; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; @@ -57,6 +58,7 @@ import org.apache.commons.lang3.time.DateUtils; import org.hamcrest.MatcherAssert; import org.junit.jupiter.api.Test; +import org.mockito.Mockito; import de.symeda.sormas.api.CaseMeasure; import de.symeda.sormas.api.Disease; @@ -64,6 +66,7 @@ import de.symeda.sormas.api.VisitOrigin; import de.symeda.sormas.api.activityascase.ActivityAsCaseDto; import de.symeda.sormas.api.activityascase.ActivityAsCaseType; +import de.symeda.sormas.api.caze.CaseBulkEditData; import de.symeda.sormas.api.caze.CaseClassification; import de.symeda.sormas.api.caze.CaseCriteria; import de.symeda.sormas.api.caze.CaseDataDto; @@ -94,6 +97,8 @@ import de.symeda.sormas.api.contact.ContactDto; import de.symeda.sormas.api.contact.ContactReferenceDto; import de.symeda.sormas.api.contact.FollowUpStatus; +import de.symeda.sormas.api.customizableenum.CustomizableEnumType; +import de.symeda.sormas.api.disease.DiseaseVariant; import de.symeda.sormas.api.document.DocumentDto; import de.symeda.sormas.api.document.DocumentRelatedEntityType; import de.symeda.sormas.api.epidata.EpiDataDto; @@ -171,6 +176,7 @@ import de.symeda.sormas.api.visit.VisitIndexDto; import de.symeda.sormas.api.visit.VisitStatus; import de.symeda.sormas.backend.AbstractBeanTest; +import de.symeda.sormas.backend.MockProducer; import de.symeda.sormas.backend.TestDataCreator; import de.symeda.sormas.backend.TestDataCreator.RDCF; import de.symeda.sormas.backend.infrastructure.district.District; @@ -3085,6 +3091,66 @@ public void testDuplicatesWithPathogenTest() { assertEquals(anthraxCase.getUuid(), duplicatedCases.get(0).getUuid()); } + @Test + public void testBulkUpdateBulkEditDiseaseVariant() { + CaseDataDto case1 = + creator.createCase(surveillanceSupervisor.toReference(), creator.createPerson().toReference(), rdcf, c -> c.setDisease(Disease.ANTHRAX)); + CaseDataDto case2 = + creator.createCase(surveillanceSupervisor.toReference(), creator.createPerson().toReference(), rdcf, c -> c.setDisease(Disease.ANTHRAX)); + + DiseaseVariant diseaseVariant = creator.createDiseaseVariant("BF.1.2", Disease.CORONAVIRUS); + Mockito + .when(MockProducer.getCustomizableEnumFacadeForConverter().getEnumValue(CustomizableEnumType.DISEASE_VARIANT, diseaseVariant.getValue())) + .thenReturn(diseaseVariant); + + CaseBulkEditData bulkEditData = new CaseBulkEditData(); + bulkEditData.setDisease(Disease.CORONAVIRUS); + bulkEditData.setDiseaseVariant(diseaseVariant); + bulkEditData.setDiseaseVariantDetails("test variant details"); + + getCaseFacade().saveBulkCase(Arrays.asList(case1.getUuid(), case2.getUuid()), bulkEditData, true, true, false, false, false, false); + + case1 = getCaseFacade().getByUuid(case1.getUuid()); + assertThat(case1.getDisease(), is(Disease.CORONAVIRUS)); + assertThat(case1.getDiseaseVariant(), is(diseaseVariant)); + assertThat(case1.getDiseaseVariantDetails(), is("test variant details")); + + case2 = getCaseFacade().getByUuid(case2.getUuid()); + assertThat(case2.getDisease(), is(Disease.CORONAVIRUS)); + assertThat(case2.getDiseaseVariant(), is(diseaseVariant)); + assertThat(case2.getDiseaseVariantDetails(), is("test variant details")); + + // unset variant + bulkEditData.setDiseaseVariant(null); + getCaseFacade().saveBulkCase(Collections.singletonList(case1.getUuid()), bulkEditData, true, true, false, false, false, false); + case1 = getCaseFacade().getByUuid(case1.getUuid()); + assertThat(case1.getDisease(), is(Disease.CORONAVIRUS)); + assertThat(case1.getDiseaseVariant(), is(nullValue())); + assertThat(case1.getDiseaseVariantDetails(), is(nullValue())); + } + + @Test + public void testBulkUpdateBulkEditDiseaseClearVariantOfChangedDisease() { + DiseaseVariant diseaseVariant = creator.createDiseaseVariant("BF.1.2", Disease.CORONAVIRUS); + Mockito + .when(MockProducer.getCustomizableEnumFacadeForConverter().getEnumValue(CustomizableEnumType.DISEASE_VARIANT, diseaseVariant.getValue())) + .thenReturn(diseaseVariant); + CaseDataDto caze = creator.createCase(surveillanceSupervisor.toReference(), creator.createPerson().toReference(), rdcf, c -> { + c.setDisease(Disease.CORONAVIRUS); + c.setDiseaseVariant(diseaseVariant); + c.setDiseaseVariantDetails("Variant details"); + }); + + CaseBulkEditData bulkEditData = new CaseBulkEditData(); + bulkEditData.setDisease(Disease.ANTHRAX); + + getCaseFacade().saveBulkCase(Collections.singletonList(caze.getUuid()), bulkEditData, true, false, false, false, false, false); + caze = getCaseFacade().getByUuid(caze.getUuid()); + assertThat(caze.getDisease(), is(Disease.ANTHRAX)); + assertThat(caze.getDiseaseVariant(), is(nullValue())); + assertThat(caze.getDiseaseVariantDetails(), is(nullValue())); + } + private static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz "; private static final SecureRandom rnd = new SecureRandom(); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/BulkCaseDataForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/BulkCaseDataForm.java index 3963592bf50..c8fc07d5644 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/BulkCaseDataForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/BulkCaseDataForm.java @@ -33,6 +33,8 @@ import java.util.Set; import java.util.stream.Collectors; +import org.apache.commons.collections.CollectionUtils; + import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.themes.ValoTheme; import com.vaadin.v7.ui.CheckBox; @@ -47,6 +49,8 @@ import de.symeda.sormas.api.caze.CaseClassification; import de.symeda.sormas.api.caze.CaseDataDto; import de.symeda.sormas.api.caze.CaseIndexDto; +import de.symeda.sormas.api.customizableenum.CustomizableEnumType; +import de.symeda.sormas.api.disease.DiseaseVariant; import de.symeda.sormas.api.event.TypeOfPlace; import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.i18n.I18nProperties; @@ -72,6 +76,8 @@ public class BulkCaseDataForm extends AbstractEditForm { private static final long serialVersionUID = 1L; private static final String DISEASE_CHECKBOX = "diseaseCheckbox"; + + private static final String DISEASE_VARIANT_CHECKBOX = "diseaseVariantCheckbox"; private static final String CLASSIFICATION_CHECKBOX = "classificationCheckbox"; private static final String INVESTIGATION_STATUS_CHECKBOX = "investigationStatusCheckbox"; private static final String OUTCOME_CHECKBOX = "outcomeCheckbox"; @@ -85,14 +91,16 @@ public class BulkCaseDataForm extends AbstractEditForm { //@formatter:off private static final String HTML_LAYOUT = - fluidRowLocsCss(VSPACE_4, DISEASE_CHECKBOX) + + fluidRowLocsCss(VSPACE_4, DISEASE_CHECKBOX) + fluidRow( - fluidColumnLoc(6, 0, CaseDataDto.DISEASE), + fluidColumnLoc(6, 0, CaseBulkEditData.DISEASE), fluidColumn(6, 0, locs( - CaseDataDto.DISEASE_DETAILS, - CaseDataDto.PLAGUE_TYPE, - CaseDataDto.DENGUE_FEVER_TYPE, - CaseDataDto.RABIES_TYPE))) + + CaseBulkEditData.DISEASE_DETAILS, + CaseBulkEditData.PLAGUE_TYPE, + CaseBulkEditData.DENGUE_FEVER_TYPE, + CaseBulkEditData.RABIES_TYPE))) + + fluidRowLocsCss(VSPACE_4, DISEASE_VARIANT_CHECKBOX) + + fluidRowLocs(CaseBulkEditData.DISEASE_VARIANT, CaseBulkEditData.DISEASE_VARIANT_DETAILS) + fluidRowLocsCss(VSPACE_4, CLASSIFICATION_CHECKBOX) + fluidRowLocs(CaseBulkEditData.CASE_CLASSIFICATION) + fluidRowLocsCss(VSPACE_4, INVESTIGATION_STATUS_CHECKBOX) + @@ -107,9 +115,9 @@ public class BulkCaseDataForm extends AbstractEditForm { CaseBulkEditData.COMMUNITY) + fluidRowLocs(FACILITY_OR_HOME_LOC, TYPE_GROUP_LOC, CaseBulkEditData.FACILITY_TYPE) + fluidRowLocs(WARNING_LAYOUT) + - fluidRowLocs(CaseDataDto.HEALTH_FACILITY, CaseBulkEditData.HEALTH_FACILITY_DETAILS) + + fluidRowLocs(CaseBulkEditData.HEALTH_FACILITY, CaseBulkEditData.HEALTH_FACILITY_DETAILS) + fluidRowLocs(SHARE_CHECKBOX) + - fluidRowLocs(CaseDataDto.DONT_SHARE_WITH_REPORTING_TOOL) + + fluidRowLocs(CaseBulkEditData.DONT_SHARE_WITH_REPORTING_TOOL) + fluidRowLocs(DONT_SHARE_WARNING_LOC); //@formatter:on @@ -118,6 +126,8 @@ public class BulkCaseDataForm extends AbstractEditForm { private boolean initialized = false; private CheckBox diseaseCheckBox; + + private CheckBox diseaseVariantCheckBox; private CheckBox classificationCheckBox; private CheckBox investigationStatusCheckBox; private CheckBox outcomeCheckBox; @@ -148,38 +158,81 @@ protected void addFields() { return; } + // Disease diseaseCheckBox = new CheckBox(I18nProperties.getCaption(Captions.bulkDisease)); getContent().addComponent(diseaseCheckBox, DISEASE_CHECKBOX); - ComboBox disease = addDiseaseField(CaseDataDto.DISEASE, false); - disease.setEnabled(false); - addField(CaseDataDto.DISEASE_DETAILS, TextField.class); - addField(CaseDataDto.PLAGUE_TYPE, NullableOptionGroup.class); - addField(CaseDataDto.DENGUE_FEVER_TYPE, NullableOptionGroup.class); - addField(CaseDataDto.RABIES_TYPE, NullableOptionGroup.class); - - if (isVisibleAllowed(CaseDataDto.DISEASE_DETAILS)) { - FieldHelper - .setVisibleWhen(getFieldGroup(), Arrays.asList(CaseDataDto.DISEASE_DETAILS), CaseDataDto.DISEASE, Arrays.asList(Disease.OTHER), true); - FieldHelper - .setRequiredWhen(getFieldGroup(), CaseDataDto.DISEASE, Arrays.asList(CaseDataDto.DISEASE_DETAILS), Arrays.asList(Disease.OTHER)); + ComboBox diseaseField = addDiseaseField(CaseBulkEditData.DISEASE, false); + diseaseField.setEnabled(false); + addField(CaseBulkEditData.DISEASE_DETAILS, TextField.class); + addField(CaseBulkEditData.PLAGUE_TYPE, NullableOptionGroup.class); + addField(CaseBulkEditData.DENGUE_FEVER_TYPE, NullableOptionGroup.class); + addField(CaseBulkEditData.RABIES_TYPE, NullableOptionGroup.class); + + if (isVisibleAllowed(CaseBulkEditData.DISEASE_DETAILS)) { + FieldHelper.setVisibleWhen( + getFieldGroup(), + Arrays.asList(CaseBulkEditData.DISEASE_DETAILS), + CaseBulkEditData.DISEASE, + Arrays.asList(Disease.OTHER), + true); + FieldHelper.setRequiredWhen( + getFieldGroup(), + CaseBulkEditData.DISEASE, + Arrays.asList(CaseBulkEditData.DISEASE_DETAILS), + Arrays.asList(Disease.OTHER)); } - if (isVisibleAllowed(CaseDataDto.PLAGUE_TYPE)) { - FieldHelper - .setVisibleWhen(getFieldGroup(), Arrays.asList(CaseDataDto.PLAGUE_TYPE), CaseDataDto.DISEASE, Arrays.asList(Disease.PLAGUE), true); + if (isVisibleAllowed(CaseBulkEditData.PLAGUE_TYPE)) { + FieldHelper.setVisibleWhen( + getFieldGroup(), + Arrays.asList(CaseBulkEditData.PLAGUE_TYPE), + CaseBulkEditData.DISEASE, + Arrays.asList(Disease.PLAGUE), + true); } - if (isVisibleAllowed(CaseDataDto.DENGUE_FEVER_TYPE)) { + if (isVisibleAllowed(CaseBulkEditData.DENGUE_FEVER_TYPE)) { FieldHelper.setVisibleWhen( getFieldGroup(), - Arrays.asList(CaseDataDto.DENGUE_FEVER_TYPE), - CaseDataDto.DISEASE, + Arrays.asList(CaseBulkEditData.DENGUE_FEVER_TYPE), + CaseBulkEditData.DISEASE, Arrays.asList(Disease.DENGUE), true); } - if (isVisibleAllowed(CaseDataDto.RABIES_TYPE)) { - FieldHelper - .setVisibleWhen(getFieldGroup(), Arrays.asList(CaseDataDto.RABIES_TYPE), CaseDataDto.DISEASE, Arrays.asList(Disease.RABIES), true); + if (isVisibleAllowed(CaseBulkEditData.RABIES_TYPE)) { + FieldHelper.setVisibleWhen( + getFieldGroup(), + Arrays.asList(CaseBulkEditData.RABIES_TYPE), + CaseBulkEditData.DISEASE, + Arrays.asList(Disease.RABIES), + true); } + // Disease variant + diseaseVariantCheckBox = new CheckBox(I18nProperties.getCaption(Captions.bulkDiseaseVariant)); + diseaseVariantCheckBox.setVisible(false); + getContent().addComponent(diseaseVariantCheckBox, DISEASE_VARIANT_CHECKBOX); + + ComboBox diseaseVariantField = addField(CaseBulkEditData.DISEASE_VARIANT, ComboBox.class); + diseaseVariantField.setEnabled(false); + TextField diseaseVariantDetailsField = addField(CaseBulkEditData.DISEASE_VARIANT_DETAILS, TextField.class); + diseaseVariantDetailsField.setVisible(false); + diseaseVariantField.setNullSelectionAllowed(true); + diseaseVariantField.setVisible(false); + + diseaseVariantField.addValueChangeListener(e -> { + DiseaseVariant diseaseVariant = (DiseaseVariant) e.getProperty().getValue(); + diseaseVariantDetailsField.setVisible(diseaseVariant != null && diseaseVariant.matchPropertyValue(DiseaseVariant.HAS_DETAILS, true)); + }); + diseaseField.addValueChangeListener( + (ValueChangeListener) valueChangeEvent -> updateDiseaseVariantField( + diseaseVariantField, + (Disease) valueChangeEvent.getProperty().getValue())); + + if (diseaseField.getValue() != null) { + Disease disease = (Disease) diseaseField.getValue(); + updateDiseaseVariantField(diseaseVariantField, disease); + } + + // Classification classificationCheckBox = new CheckBox(I18nProperties.getCaption(Captions.bulkCaseClassification)); getContent().addComponent(classificationCheckBox, CLASSIFICATION_CHECKBOX); investigationStatusCheckBox = new CheckBox(I18nProperties.getCaption(Captions.bulkInvestigationStatus)); @@ -243,7 +296,7 @@ protected void addFields() { facilityOrHome.setEnabled(false); CssStyles.style(facilityOrHome, ValoTheme.OPTIONGROUP_HORIZONTAL); - healthFacilityDetails = addField(CaseDataDto.HEALTH_FACILITY_DETAILS, TextField.class); + healthFacilityDetails = addField(CaseBulkEditData.HEALTH_FACILITY_DETAILS, TextField.class); healthFacilityDetails.setVisible(false); facilityTypeGroup = ComboBoxHelper.createComboBoxV7(); @@ -251,7 +304,7 @@ protected void addFields() { addCustomField(facilityTypeGroup, TYPE_GROUP_LOC, I18nProperties.getCaption(Captions.Facility_typeGroup)); facilityTypeGroup.addItems(FacilityTypeGroup.getAccomodationGroups()); facilityTypeGroup.setEnabled(false); - facilityType = addField(CaseDataDto.FACILITY_TYPE, ComboBox.class); + facilityType = addField(CaseBulkEditData.FACILITY_TYPE, ComboBox.class); facilityType.setEnabled(false); ComboBox facility = addInfrastructureField(CaseBulkEditData.HEALTH_FACILITY); facility.setImmediate(true); @@ -385,6 +438,12 @@ protected void addFields() { } FieldHelper.setRequiredWhen(getFieldGroup(), diseaseCheckBox, Arrays.asList(CaseBulkEditData.DISEASE), Arrays.asList(true)); + FieldHelper.addSoftRequiredStyleWhen( + getFieldGroup(), + diseaseVariantCheckBox, + Arrays.asList(CaseBulkEditData.DISEASE_VARIANT), + Arrays.asList(true), + null); FieldHelper .setRequiredWhen(getFieldGroup(), classificationCheckBox, Arrays.asList(CaseBulkEditData.CASE_CLASSIFICATION), Arrays.asList(true)); FieldHelper @@ -413,7 +472,21 @@ protected void addFields() { false, null); diseaseCheckBox.addValueChangeListener(e -> { - disease.setEnabled((boolean) e.getProperty().getValue()); + boolean checked = (boolean) e.getProperty().getValue(); + diseaseField.setEnabled(checked); + if (!checked) { + diseaseField.setValue(null); + } + + updateDiseaseVariantField(diseaseVariantField, null); + }); + diseaseVariantCheckBox.addValueChangeListener(e -> { + boolean checked = (boolean) e.getProperty().getValue(); + diseaseVariantField.setEnabled(checked); + if (!checked) { + diseaseVariantField.setValue(null); + diseaseVariantDetailsField.setValue(null); + } }); classificationCheckBox.addValueChangeListener(e -> { caseClassification.setEnabled((boolean) e.getProperty().getValue()); @@ -451,6 +524,10 @@ public CheckBox getDiseaseCheckBox() { return diseaseCheckBox; } + public CheckBox getDiseaseVariantCheckBox() { + return diseaseVariantCheckBox; + } + public CheckBox getClassificationCheckBox() { return classificationCheckBox; } @@ -512,4 +589,18 @@ private void updateFacilityFields(ComboBox cbFacility, TextField tfFacilityDetai tfFacilityDetails.clear(); } } + + private void updateDiseaseVariantField(ComboBox diseaseVariantField, Disease disease) { + List diseaseVariants = + FacadeProvider.getCustomizableEnumFacade().getEnumValues(CustomizableEnumType.DISEASE_VARIANT, disease); + FieldHelper.updateItems(diseaseVariantField, diseaseVariants); + boolean visible = disease != null && CollectionUtils.isNotEmpty(diseaseVariants); + + diseaseVariantField.setVisible(visible); + + diseaseVariantCheckBox.setVisible(visible); + if (!visible) { + diseaseVariantCheckBox.setValue(false); + } + } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java index 4708863cdc9..f9357b39c44 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java @@ -1025,6 +1025,7 @@ public void showBulkCaseDataEditComponent(Collection CaseBulkEditData updatedBulkEditData = form.getValue(); boolean diseaseChange = form.getDiseaseCheckBox().getValue(); + boolean diseaseVariantChange = form.getDiseaseVariantCheckBox().getValue(); boolean classificationChange = form.getClassificationCheckBox().getValue(); boolean investigationStatusChange = form.getInvestigationStatusCheckBox().getValue(); boolean outcomeChange = form.getOutcomeCheckBox().getValue(); @@ -1046,6 +1047,7 @@ public void showBulkCaseDataEditComponent(Collection selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList()), updatedBulkEditData, diseaseChange, + diseaseVariantChange, classificationChange, investigationStatusChange, outcomeChange, @@ -1062,6 +1064,7 @@ BulkOperationHandler. forBulkEdit() selectedEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList()), updatedBulkEditData, diseaseChange, + diseaseVariantChange, classificationChange, investigationStatusChange, outcomeChange, From 76be82bb5d08fbdfcebf2ed4de8a2ebce969639f Mon Sep 17 00:00:00 2001 From: Martin Wahnschaffe Date: Fri, 28 Jul 2023 10:46:37 +0200 Subject: [PATCH 131/174] #12045 fixed argument when running keyclock docker compose without the shell script --- sormas-base/setup/keycloak/docker-compose.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sormas-base/setup/keycloak/docker-compose.yml b/sormas-base/setup/keycloak/docker-compose.yml index 765bd68c049..a588e5dfb6a 100644 --- a/sormas-base/setup/keycloak/docker-compose.yml +++ b/sormas-base/setup/keycloak/docker-compose.yml @@ -10,6 +10,7 @@ services: restart: unless-stopped labels: - autoheal=true + #image: sormas-docker-keycloak:latest image: hzibraunschweig/sormas-keycloak:${SORMAS_DOCKER_VERSION} ports: - ${KEYCLOAK_PORT}:8080 @@ -21,7 +22,7 @@ services: - KC_DB_USERNAME=${KEYCLOAK_DB_USER} - KC_DB_PASSWORD=${KEYCLOAK_DB_PASSWORD} - PROXY_ADDRESS_FORWARDING=true - - SORMAS_HOST_URL=${SORMAS_HOST} + - SORMAS_SERVER_URL=${SORMAS_SERVER_URL} - KEYCLOAK_SORMAS_UI_SECRET=${KEYCLOAK_SORMAS_UI_SECRET} - KEYCLOAK_SORMAS_REST_SECRET=${KEYCLOAK_SORMAS_REST_SECRET} - KEYCLOAK_SORMAS_BACKEND_SECRET=${KEYCLOAK_SORMAS_BACKEND_SECRET} From 7012fd04d920772b63cbd5f6f6227a03bbc26e01 Mon Sep 17 00:00:00 2001 From: Levente Gal <62599627+leventegal-she@users.noreply.github.com> Date: Fri, 28 Jul 2023 12:13:35 +0300 Subject: [PATCH 132/174] =?UTF-8?q?#12284=20Add=20the=20'See=20personal=20?= =?UTF-8?q?data=20inside=20jurisdiction'=20user=20right=20to=20=E2=80=A6?= =?UTF-8?q?=20(#12354)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * #12284 Add the 'See personal data inside jurisdiction' user right to the default Environmental Surveillance User * #12284 Add the 'See personal data inside jurisdiction' user right to the default Environmental Surveillance User - update change date for updated roles so they get synced into the mobile app --------- Co-authored-by: Levente Gal --- .../sormas/api/user/DefaultUserRole.java | 1 + .../src/main/resources/sql/sormas_schema.sql | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/user/DefaultUserRole.java b/sormas-api/src/main/java/de/symeda/sormas/api/user/DefaultUserRole.java index de881d5aa84..28a9172e7c1 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/user/DefaultUserRole.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/user/DefaultUserRole.java @@ -1492,6 +1492,7 @@ public Set getDefaultUserRights() { TASK_EDIT, TASK_ASSIGN, TASK_EXPORT, + SEE_PERSONAL_DATA_IN_JURISDICTION, SEE_SENSITIVE_DATA_IN_JURISDICTION, SORMAS_REST, SORMAS_UI)); diff --git a/sormas-backend/src/main/resources/sql/sormas_schema.sql b/sormas-backend/src/main/resources/sql/sormas_schema.sql index dc3a91cac90..421a75933f5 100644 --- a/sormas-backend/src/main/resources/sql/sormas_schema.sql +++ b/sormas-backend/src/main/resources/sql/sormas_schema.sql @@ -12489,4 +12489,20 @@ ALTER TABLE testreport ADD CONSTRAINT fk_testreport_prescribercountry_id FOREIGN INSERT INTO schema_version (version_number, comment) VALUES (518, 'Add prescriber fields to pathogen tests and test reports #12318'); --- *** Insert new sql commands BEFORE this line. Remember to always consider _history tables. *** +-- 2023-07-26 Add the 'See personal data inside jurisdiction' user right to the default Environmental Surveillance User #12284 + +DO $$ + DECLARE ur RECORD; + BEGIN + FOR ur IN SELECT id FROM userroles WHERE linkeddefaultuserrole = 'ENVIRONMENTAL_SURVEILLANCE_USER' + LOOP + IF NOT EXISTS (SELECT 1 FROM userroles_userrights WHERE userrole_id = ur.id AND userright = 'SEE_PERSONAL_DATA_IN_JURISDICTION') THEN + INSERT INTO userroles_userrights (userrole_id, userright) VALUES (ur.id, 'SEE_PERSONAL_DATA_IN_JURISDICTION'); + UPDATE userroles set changedate = now() WHERE id = ur.id AND linkeddefaultuserrole = 'ENVIRONMENTAL_SURVEILLANCE_USER'; + END IF; + END LOOP; + END; +$$ LANGUAGE plpgsql; + +INSERT INTO schema_version (version_number, comment) VALUES (519, 'Add the ''See personal data inside jurisdiction'' user right to the default Environmental Surveillance User #12284'); +-- *** Insert new sql commands BEFORE this line. Remember to always consider _history tables. *** \ No newline at end of file From 41317a0ba111a8f2de977341536fa75963ed321f Mon Sep 17 00:00:00 2001 From: Razvan Date: Fri, 28 Jul 2023 12:21:11 +0300 Subject: [PATCH 133/174] SORQA-993 : updates --- .../immunizations/VaccineNameValues.java | 2 +- .../aCommonComponents/SideCards.java | 1 + .../messages/MessagesDirectoryPage.java | 11 +- .../src/main/java/recorders/StepsLogger.java | 3 +- .../entities/services/EventService.java | 3 +- .../services/api/demis/DemisApiService.java | 25 +-- .../steps/api/demisSteps/DemisSteps.java | 104 +++++----- .../aCommonComponents/SideCardsSteps.java | 23 ++- .../application/cases/CreateNewCaseSteps.java | 63 +++--- .../events/CreateNewEventSteps.java | 55 +++--- .../application/events/EditEventSteps.java | 105 +++++----- .../messages/MessagesDirectorySteps.java | 33 ++-- .../samples/CreateNewSampleSteps.java | 55 +++--- .../application/samples/EditSampleSteps.java | 63 +++--- .../web/application/survnet/SurvNetSteps.java | 182 +++++++++--------- .../features/sanity/web/Columns.feature | 4 +- 16 files changed, 368 insertions(+), 364 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/immunizations/VaccineNameValues.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/immunizations/VaccineNameValues.java index 14044a2272c..1dac65281ee 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/immunizations/VaccineNameValues.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/immunizations/VaccineNameValues.java @@ -44,4 +44,4 @@ public enum VaccineNameValues { public static String getRandomVaccineName() { return String.valueOf(VaccineNameValues.values()[random.nextInt(values().length)].vaccineName); } -} \ No newline at end of file +} diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/aCommonComponents/SideCards.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/aCommonComponents/SideCards.java index 15630cb1175..9b9b5a36360 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/aCommonComponents/SideCards.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/aCommonComponents/SideCards.java @@ -58,6 +58,7 @@ public static By checkTextInReportSideComponent(String text) { "//div[@location='sormasToSormas']//div[@class='v-slot v-slot-s-list-entry v-slot-s-list-entry-no-border']"); public static final By SHARE_SORMAS_2_SORMAS_POPUP_BUTTON = By.cssSelector(".popupContent #commit"); + public static By getEditSampleButtonByNumber(Integer number) { return By.xpath(String.format("(//div[contains(@id, 'edit-sample')])[%x]", number)); } diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java index 3da9cb5842b..27c7e31ebe7 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java @@ -138,10 +138,13 @@ public static By getProcessStatusByIndex(int index) { By.xpath("(//input[contains(@id, 'labDetails')])[2]"); public static final By NEW_SAMPLE_FORM_SECOND_PATHOGEN_LABORATORY_NAME = By.xpath("(//input[contains(@id, 'labDetails')])[3]"); - public static final By MULTIPLE_SAMPLES_HEADER = By.xpath("//div[@class= 'v-window-header'][text()='Mehrere Proben']"); - public static final By CREATE_NEW_SAMPLE_CHECKBOX = By.xpath("//span[@class= 'v-radiobutton v-select-option']//label[text()='Neue Probe erstellen']"); + public static final By MULTIPLE_SAMPLES_HEADER = + By.xpath("//div[@class= 'v-window-header'][text()='Mehrere Proben']"); + public static final By CREATE_NEW_SAMPLE_CHECKBOX = + By.xpath( + "//span[@class= 'v-radiobutton v-select-option']//label[text()='Neue Probe erstellen']"); public static final By NEW_SAMPLE_FORM_FIRST_PATHOGEN_TEST_TYPE_INPUT = - By.xpath("(//div[contains(@id, 'testType')]//input)[1]"); + By.xpath("(//div[contains(@id, 'testType')]//input)[1]"); public static final By NEW_SAMPLE_FORM_SECOND_PATHOGEN_TEST_TYPE_INPUT = - By.xpath("(//div[contains(@id, 'testType')]//input)[2]"); + By.xpath("(//div[contains(@id, 'testType')]//input)[2]"); } diff --git a/sormas-e2e-tests/src/main/java/recorders/StepsLogger.java b/sormas-e2e-tests/src/main/java/recorders/StepsLogger.java index c3573ab185e..26b0378867b 100644 --- a/sormas-e2e-tests/src/main/java/recorders/StepsLogger.java +++ b/sormas-e2e-tests/src/main/java/recorders/StepsLogger.java @@ -115,8 +115,7 @@ public void takeScreenshot() { @SneakyThrows private List collectWarningElements() { - List warningsList = - driver.findElements(By.xpath("//*[contains(@class,'error')]")); + List warningsList = driver.findElements(By.xpath("//*[contains(@class,'error')]")); List attachments = new ArrayList<>(); String fileName = "warning_element%s.jpg"; for (int i = 0; i < warningsList.size(); i++) { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/EventService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/EventService.java index 1096ab103a0..a026d51c191 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/EventService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/EventService.java @@ -17,14 +17,13 @@ import com.github.javafaker.Faker; import com.google.inject.Inject; +import java.time.LocalDate; import org.sormas.e2etests.entities.pojo.web.Event; import org.sormas.e2etests.enums.CommunityValues; import org.sormas.e2etests.enums.DiseasesValues; import org.sormas.e2etests.enums.DistrictsValues; import org.sormas.e2etests.enums.RegionsValues; -import java.time.LocalDate; - public class EventService { private final Faker faker; diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java index 5399568087c..c0cfbe3c275 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java @@ -17,6 +17,13 @@ */ package org.sormas.e2etests.entities.services.api.demis; +import static org.sormas.e2etests.steps.BaseSteps.locale; + +import java.net.SocketTimeoutException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.UUID; +import javax.inject.Inject; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import okhttp3.MediaType; @@ -30,14 +37,6 @@ import org.sormas.e2etests.envconfig.manager.RunningConfiguration; import org.sormas.e2etests.helpers.api.demis.okhttpclient.SormasOkHttpClient; -import javax.inject.Inject; -import java.net.SocketTimeoutException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.UUID; - -import static org.sormas.e2etests.steps.BaseSteps.locale; - @Slf4j public class DemisApiService { @@ -259,9 +258,10 @@ public String prepareLabNotificationFileWithTwoSamples( } public String prepareLabNotificationFileWithOneExistingFacility( - String patientFirstName, String patientLastName) { + String patientFirstName, String patientLastName) { DemisData demisData = runningConfiguration.getDemisData(locale); - String file = "src/main/resources/demisJsonTemplates/labNotificationTemplateWithExistingFacility.json"; + String file = + "src/main/resources/demisJsonTemplates/labNotificationTemplateWithExistingFacility.json"; String json = readFileAsString(file); json = json.replace("", UUID.randomUUID().toString()); json = json.replace("\"\"", "\"" + patientLastName + "\""); @@ -273,9 +273,10 @@ public String prepareLabNotificationFileWithOneExistingFacility( } public String prepareLabNotificationFileWithMultiplePathogenOneSample( - String patientFirstName, String patientLastName) { + String patientFirstName, String patientLastName) { DemisData demisData = runningConfiguration.getDemisData(locale); - String file = "src/main/resources/demisJsonTemplates/labNotificationTemplateMultiplePathogen.json"; + String file = + "src/main/resources/demisJsonTemplates/labNotificationTemplateMultiplePathogen.json"; String json = readFileAsString(file); json = json.replace("", UUID.randomUUID().toString()); json = json.replace("\"\"", "\"" + demisData.getPostalCode() + "\""); diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java index 6b4e7ca7ffe..0f499c4621c 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java @@ -1,35 +1,5 @@ package org.sormas.e2etests.steps.api.demisSteps; -import com.github.javafaker.Faker; -import cucumber.api.java8.En; -import lombok.extern.slf4j.Slf4j; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; -import org.sormas.e2etests.entities.pojo.web.Event; -import org.sormas.e2etests.entities.services.EventService; -import org.sormas.e2etests.entities.services.api.demis.DemisApiService; -import org.sormas.e2etests.envconfig.dto.demis.DemisData; -import org.sormas.e2etests.envconfig.manager.RunningConfiguration; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.steps.BaseSteps; -import org.sormas.e2etests.steps.web.application.messages.MessagesTableViewHeaders; -import org.testng.Assert; -import org.testng.asserts.SoftAssert; - -import javax.inject.Inject; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.PERSON_ID_NAME_CONTACT_INFORMATION_LIKE_INPUT; import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.DATE_OF_REPORT_INPUT; import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.FIRST_NAME_INPUT; @@ -107,6 +77,35 @@ import static org.sormas.e2etests.pages.application.samples.EditSamplePage.PCR_TEST_SPECIFICATION_INPUT; import static org.sormas.e2etests.steps.BaseSteps.locale; +import com.github.javafaker.Faker; +import cucumber.api.java8.En; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.sormas.e2etests.entities.pojo.web.Event; +import org.sormas.e2etests.entities.services.EventService; +import org.sormas.e2etests.entities.services.api.demis.DemisApiService; +import org.sormas.e2etests.envconfig.dto.demis.DemisData; +import org.sormas.e2etests.envconfig.manager.RunningConfiguration; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.steps.BaseSteps; +import org.sormas.e2etests.steps.web.application.messages.MessagesTableViewHeaders; +import org.testng.Assert; +import org.testng.asserts.SoftAssert; + @Slf4j public class DemisSteps implements En { @@ -942,9 +941,13 @@ public DemisSteps( () -> { patientFirstName = faker.name().firstName(); patientLastName = faker.name().lastName(); - String json = demisApiService.prepareLabNotificationFileWithOneExistingFacility(patientFirstName, patientLastName); + String json = + demisApiService.prepareLabNotificationFileWithOneExistingFacility( + patientFirstName, patientLastName); - Assert.assertTrue(demisApiService.sendLabRequest(json, loginToken), "Failed to send laboratory request"); + Assert.assertTrue( + demisApiService.sendLabRequest(json, loginToken), + "Failed to send laboratory request"); }); When( @@ -952,30 +955,37 @@ public DemisSteps( () -> { patientFirstName = faker.name().firstName(); patientLastName = faker.name().lastName(); - String json = demisApiService.prepareLabNotificationFileWithMultiplePathogenOneSample(patientFirstName, patientLastName); + String json = + demisApiService.prepareLabNotificationFileWithMultiplePathogenOneSample( + patientFirstName, patientLastName); - Assert.assertTrue(demisApiService.sendLabRequest(json, loginToken), "Failed to send laboratory request"); + Assert.assertTrue( + demisApiService.sendLabRequest(json, loginToken), + "Failed to send laboratory request"); }); And( "^I verify that test type for \"([^\"]*)\" pathogen is prefilled with \"([^\"]*)\" in New Sample form while processing a DEMIS LabMessage$", (String pathogen, String testType) -> { - webDriverHelpers.waitUntilIdentifiedElementIsPresent(NEW_SAMPLE_FORM_FIRST_PATHOGEN_TEST_TYPE_INPUT); + webDriverHelpers.waitUntilIdentifiedElementIsPresent( + NEW_SAMPLE_FORM_FIRST_PATHOGEN_TEST_TYPE_INPUT); switch (pathogen) { case "first": - softly.assertEquals( - webDriverHelpers.getValueFromWebElement(NEW_SAMPLE_FORM_FIRST_PATHOGEN_TEST_TYPE_INPUT), - testType, - "The disease variant is incorrect"); - softly.assertAll(); - break; + softly.assertEquals( + webDriverHelpers.getValueFromWebElement( + NEW_SAMPLE_FORM_FIRST_PATHOGEN_TEST_TYPE_INPUT), + testType, + "The disease variant is incorrect"); + softly.assertAll(); + break; case "second": - softly.assertEquals( - webDriverHelpers.getValueFromWebElement(NEW_SAMPLE_FORM_SECOND_PATHOGEN_TEST_TYPE_INPUT), - testType, - "The disease variant is incorrect"); - softly.assertAll(); - break; + softly.assertEquals( + webDriverHelpers.getValueFromWebElement( + NEW_SAMPLE_FORM_SECOND_PATHOGEN_TEST_TYPE_INPUT), + testType, + "The disease variant is incorrect"); + softly.assertAll(); + break; } }); } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/aCommonComponents/SideCardsSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/aCommonComponents/SideCardsSteps.java index 3d0527ac631..377569a4b76 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/aCommonComponents/SideCardsSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/aCommonComponents/SideCardsSteps.java @@ -18,18 +18,6 @@ package org.sormas.e2etests.steps.web.application.aCommonComponents; -import com.github.javafaker.Faker; -import cucumber.api.java8.En; -import lombok.SneakyThrows; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.steps.BaseSteps; -import org.testng.asserts.SoftAssert; - -import javax.inject.Inject; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.util.concurrent.TimeUnit; - import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.ADDED_SAMPLES_IN_SAMPLE_CARD; import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.EDIT_SAMPLE_BUTTON; import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.HANDOVER_SIDE_CARD; @@ -45,6 +33,17 @@ import static org.sormas.e2etests.pages.application.contacts.EditContactPage.NUMBER_OF_TESTS_IN_SAMPLES; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.ONE_TEST_IN_SAMPLES_DE; +import com.github.javafaker.Faker; +import cucumber.api.java8.En; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.concurrent.TimeUnit; +import javax.inject.Inject; +import lombok.SneakyThrows; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.steps.BaseSteps; +import org.testng.asserts.SoftAssert; + public class SideCardsSteps implements En { private final WebDriverHelpers webDriverHelpers; public static Faker faker; diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CreateNewCaseSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CreateNewCaseSteps.java index b20e80840d2..d2334eb78c5 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CreateNewCaseSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CreateNewCaseSteps.java @@ -18,38 +18,6 @@ package org.sormas.e2etests.steps.web.application.cases; -import com.github.javafaker.Faker; -import cucumber.api.java8.En; -import io.restassured.http.Method; -import lombok.SneakyThrows; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; -import org.sormas.e2etests.entities.pojo.api.Request; -import org.sormas.e2etests.entities.pojo.web.Case; -import org.sormas.e2etests.entities.services.CaseService; -import org.sormas.e2etests.enums.GenderValues; -import org.sormas.e2etests.helpers.RestAssuredClient; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.helpers.files.FilesHelper; -import org.sormas.e2etests.pages.application.cases.EditCasePage; -import org.sormas.e2etests.state.ApiState; -import org.sormas.e2etests.steps.BaseSteps; -import org.testng.asserts.SoftAssert; - -import javax.inject.Inject; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.time.format.TextStyle; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Random; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - import static org.sormas.e2etests.constants.api.Endpoints.CASES_PATH; import static org.sormas.e2etests.entities.pojo.helpers.ShortUUIDGenerator.generateShortUUID; import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CASE_APPLY_FILTERS_BUTTON; @@ -163,6 +131,37 @@ import static org.sormas.e2etests.steps.web.application.contacts.CreateNewContactSteps.contact; import static org.sormas.e2etests.steps.web.application.persons.PersonDirectorySteps.personSharedForAllEntities; +import com.github.javafaker.Faker; +import cucumber.api.java8.En; +import io.restassured.http.Method; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.TextStyle; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import javax.inject.Inject; +import lombok.SneakyThrows; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.sormas.e2etests.entities.pojo.api.Request; +import org.sormas.e2etests.entities.pojo.web.Case; +import org.sormas.e2etests.entities.services.CaseService; +import org.sormas.e2etests.enums.GenderValues; +import org.sormas.e2etests.helpers.RestAssuredClient; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.helpers.files.FilesHelper; +import org.sormas.e2etests.pages.application.cases.EditCasePage; +import org.sormas.e2etests.state.ApiState; +import org.sormas.e2etests.steps.BaseSteps; +import org.testng.asserts.SoftAssert; + public class CreateNewCaseSteps implements En { private final WebDriverHelpers webDriverHelpers; diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/CreateNewEventSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/CreateNewEventSteps.java index 712ed623944..1746d3f7dc7 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/CreateNewEventSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/CreateNewEventSteps.java @@ -18,34 +18,6 @@ package org.sormas.e2etests.steps.web.application.events; -import com.github.javafaker.Faker; -import com.opencsv.CSVParser; -import com.opencsv.CSVParserBuilder; -import com.opencsv.CSVReader; -import com.opencsv.CSVReaderBuilder; -import com.opencsv.exceptions.CsvException; -import cucumber.api.java8.En; -import lombok.extern.slf4j.Slf4j; -import org.sormas.e2etests.entities.pojo.web.Event; -import org.sormas.e2etests.entities.services.EventService; -import org.sormas.e2etests.enums.DistrictsValues; -import org.sormas.e2etests.enums.RegionsValues; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.testng.asserts.SoftAssert; - -import javax.inject.Inject; -import java.io.FileReader; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.time.LocalDate; -import java.time.LocalTime; -import java.time.format.DateTimeFormatter; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; - import static org.sormas.e2etests.pages.application.events.CreateNewEventPage.DISEASE_COMBOBOX; import static org.sormas.e2etests.pages.application.events.CreateNewEventPage.DISEASE_VARIANT_COMBOBOX; import static org.sormas.e2etests.pages.application.events.CreateNewEventPage.END_DATA_EVENT; @@ -75,6 +47,33 @@ import static org.sormas.e2etests.pages.application.events.EditEventPage.UUID_INPUT; import static org.sormas.e2etests.pages.application.events.EventDirectoryPage.NEW_EVENT_BUTTON; +import com.github.javafaker.Faker; +import com.opencsv.CSVParser; +import com.opencsv.CSVParserBuilder; +import com.opencsv.CSVReader; +import com.opencsv.CSVReaderBuilder; +import com.opencsv.exceptions.CsvException; +import cucumber.api.java8.En; +import java.io.FileReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import org.sormas.e2etests.entities.pojo.web.Event; +import org.sormas.e2etests.entities.services.EventService; +import org.sormas.e2etests.enums.DistrictsValues; +import org.sormas.e2etests.enums.RegionsValues; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.testng.asserts.SoftAssert; + @Slf4j public class CreateNewEventSteps implements En { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java index 67beedad457..4144e737de5 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java @@ -18,59 +18,6 @@ package org.sormas.e2etests.steps.web.application.events; -import com.github.javafaker.Faker; -import com.opencsv.CSVParser; -import com.opencsv.CSVParserBuilder; -import com.opencsv.CSVReader; -import com.opencsv.CSVReaderBuilder; -import com.opencsv.exceptions.CsvException; -import cucumber.api.java8.En; -import lombok.extern.slf4j.Slf4j; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.apache.poi.xwpf.usermodel.XWPFParagraph; -import org.openqa.selenium.By; -import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; -import org.sormas.e2etests.entities.pojo.web.Event; -import org.sormas.e2etests.entities.pojo.web.EventGroup; -import org.sormas.e2etests.entities.pojo.web.EventHandout; -import org.sormas.e2etests.entities.pojo.web.EventParticipant; -import org.sormas.e2etests.entities.pojo.web.Person; -import org.sormas.e2etests.entities.services.EventDocumentService; -import org.sormas.e2etests.entities.services.EventGroupService; -import org.sormas.e2etests.entities.services.EventParticipantService; -import org.sormas.e2etests.entities.services.EventService; -import org.sormas.e2etests.enums.DistrictsValues; -import org.sormas.e2etests.enums.GenderValues; -import org.sormas.e2etests.enums.RegionsValues; -import org.sormas.e2etests.envconfig.manager.RunningConfiguration; -import org.sormas.e2etests.helpers.AssertHelpers; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.helpers.files.FilesHelper; -import org.sormas.e2etests.pages.application.contacts.EditContactPage; -import org.sormas.e2etests.pages.application.events.EditEventPage; -import org.sormas.e2etests.state.ApiState; -import org.sormas.e2etests.steps.web.application.contacts.CreateNewContactSteps; -import org.sormas.e2etests.steps.web.application.contacts.EditContactSteps; -import org.sormas.e2etests.steps.web.application.persons.PersonDirectorySteps; -import org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps; -import org.testng.Assert; -import org.testng.asserts.SoftAssert; - -import javax.inject.Inject; -import java.io.FileInputStream; -import java.io.FileReader; -import java.io.IOException; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.time.format.TextStyle; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.Random; -import java.util.concurrent.TimeUnit; - import static org.sormas.e2etests.pages.application.actions.CreateNewActionPage.NEW_ACTION_POPUP; import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.ALL_RESULTS_CHECKBOX; import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.CONFIRM_POPUP; @@ -263,6 +210,58 @@ import static org.sormas.e2etests.pages.application.samples.EditSamplePage.DELETE_SAMPLE_REASON_POPUP; import static org.sormas.e2etests.steps.BaseSteps.locale; +import com.github.javafaker.Faker; +import com.opencsv.CSVParser; +import com.opencsv.CSVParserBuilder; +import com.opencsv.CSVReader; +import com.opencsv.CSVReaderBuilder; +import com.opencsv.exceptions.CsvException; +import cucumber.api.java8.En; +import java.io.FileInputStream; +import java.io.FileReader; +import java.io.IOException; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.TextStyle; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.Random; +import java.util.concurrent.TimeUnit; +import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.apache.poi.xwpf.usermodel.XWPFParagraph; +import org.openqa.selenium.By; +import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; +import org.sormas.e2etests.entities.pojo.web.Event; +import org.sormas.e2etests.entities.pojo.web.EventGroup; +import org.sormas.e2etests.entities.pojo.web.EventHandout; +import org.sormas.e2etests.entities.pojo.web.EventParticipant; +import org.sormas.e2etests.entities.pojo.web.Person; +import org.sormas.e2etests.entities.services.EventDocumentService; +import org.sormas.e2etests.entities.services.EventGroupService; +import org.sormas.e2etests.entities.services.EventParticipantService; +import org.sormas.e2etests.entities.services.EventService; +import org.sormas.e2etests.enums.DistrictsValues; +import org.sormas.e2etests.enums.GenderValues; +import org.sormas.e2etests.enums.RegionsValues; +import org.sormas.e2etests.envconfig.manager.RunningConfiguration; +import org.sormas.e2etests.helpers.AssertHelpers; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.helpers.files.FilesHelper; +import org.sormas.e2etests.pages.application.contacts.EditContactPage; +import org.sormas.e2etests.pages.application.events.EditEventPage; +import org.sormas.e2etests.state.ApiState; +import org.sormas.e2etests.steps.web.application.contacts.CreateNewContactSteps; +import org.sormas.e2etests.steps.web.application.contacts.EditContactSteps; +import org.sormas.e2etests.steps.web.application.persons.PersonDirectorySteps; +import org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps; +import org.testng.Assert; +import org.testng.asserts.SoftAssert; + @Slf4j public class EditEventSteps implements En { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java index 9d2c9a81b65..b64d076a611 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java @@ -1,22 +1,5 @@ package org.sormas.e2etests.steps.web.application.messages; -import cucumber.api.java8.En; -import lombok.extern.slf4j.Slf4j; -import org.openqa.selenium.Keys; -import org.openqa.selenium.interactions.Actions; -import org.sormas.e2etests.helpers.AssertHelpers; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.steps.BaseSteps; -import org.testng.Assert; -import org.testng.asserts.SoftAssert; - -import javax.inject.Inject; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.ACTION_CONFIRM_POPUP_BUTTON; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.ACTION_YES_BUTTON; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CLOSE_POPUP; @@ -57,6 +40,22 @@ import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.getProcessMessageButtonByIndex; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.getProcessStatusByIndex; +import cucumber.api.java8.En; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; +import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import org.openqa.selenium.Keys; +import org.openqa.selenium.interactions.Actions; +import org.sormas.e2etests.helpers.AssertHelpers; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.steps.BaseSteps; +import org.testng.Assert; +import org.testng.asserts.SoftAssert; + @Slf4j public class MessagesDirectorySteps implements En { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/CreateNewSampleSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/CreateNewSampleSteps.java index 663ce528009..0c360484e5e 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/CreateNewSampleSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/CreateNewSampleSteps.java @@ -18,34 +18,6 @@ package org.sormas.e2etests.steps.web.application.samples; -import com.github.javafaker.Faker; -import cucumber.api.java8.En; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; -import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; -import org.sormas.e2etests.entities.pojo.web.Sample; -import org.sormas.e2etests.entities.pojo.web.SampleAdditionalTest; -import org.sormas.e2etests.entities.services.SampleAdditionalTestService; -import org.sormas.e2etests.entities.services.SampleService; -import org.sormas.e2etests.enums.PathogenTestResults; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.state.ApiState; -import org.sormas.e2etests.steps.BaseSteps; -import org.testng.asserts.SoftAssert; - -import javax.inject.Inject; -import java.time.LocalDate; -import java.time.LocalTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.ACTION_CONFIRM_POPUP_BUTTON; import static org.sormas.e2etests.pages.application.cases.EditCasePage.SAMPLES_CARD_DATE_AND_TIME_OF_RESULT; import static org.sormas.e2etests.pages.application.cases.EditCasePage.SAMPLES_CARD_DATE_OF_COLLECTED_SAMPLE; @@ -147,6 +119,33 @@ import static org.sormas.e2etests.pages.application.samples.SamplesDirectoryPage.SAMPLE_RECEIVED_CHECKBOX; import static org.sormas.e2etests.pages.application.samples.SamplesDirectoryPage.SAMPLE_SHIPPED_CHECKBOX; +import com.github.javafaker.Faker; +import cucumber.api.java8.En; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import javax.inject.Inject; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; +import org.sormas.e2etests.entities.pojo.web.Sample; +import org.sormas.e2etests.entities.pojo.web.SampleAdditionalTest; +import org.sormas.e2etests.entities.services.SampleAdditionalTestService; +import org.sormas.e2etests.entities.services.SampleService; +import org.sormas.e2etests.enums.PathogenTestResults; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.state.ApiState; +import org.sormas.e2etests.steps.BaseSteps; +import org.testng.asserts.SoftAssert; + public class CreateNewSampleSteps implements En { public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("M/d/yyyy"); public static final DateTimeFormatter DATE_FORMATTER_DE = DateTimeFormatter.ofPattern("d.M.yyyy"); diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/EditSampleSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/EditSampleSteps.java index 1c4034e50f8..27a810a484c 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/EditSampleSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/samples/EditSampleSteps.java @@ -18,22 +18,6 @@ package org.sormas.e2etests.steps.web.application.samples; -import cucumber.api.java8.En; -import org.openqa.selenium.By; -import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; -import org.sormas.e2etests.entities.pojo.web.Sample; -import org.sormas.e2etests.entities.services.SampleService; -import org.sormas.e2etests.entities.services.api.demis.DemisApiService; -import org.sormas.e2etests.envconfig.manager.RunningConfiguration; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.state.ApiState; -import org.testng.asserts.SoftAssert; - -import javax.inject.Inject; -import java.time.LocalDate; -import java.time.LocalTime; -import java.time.format.DateTimeFormatter; - import static org.sormas.e2etests.pages.application.samples.CreateNewSamplePage.SAVE_EDIT_SAMPLE_BUTTON; import static org.sormas.e2etests.pages.application.samples.EditSamplePage.ADDIITONAL_NEW_TEST_RESULT_BUTTON; import static org.sormas.e2etests.pages.application.samples.EditSamplePage.BACK_TO_CASE_DE_BUTTON; @@ -73,6 +57,21 @@ import static org.sormas.e2etests.pages.application.samples.SamplesDirectoryPage.SAMPLE_SEARCH_INPUT; import static org.sormas.e2etests.steps.BaseSteps.locale; +import cucumber.api.java8.En; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import javax.inject.Inject; +import org.openqa.selenium.By; +import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; +import org.sormas.e2etests.entities.pojo.web.Sample; +import org.sormas.e2etests.entities.services.SampleService; +import org.sormas.e2etests.entities.services.api.demis.DemisApiService; +import org.sormas.e2etests.envconfig.manager.RunningConfiguration; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.state.ApiState; +import org.testng.asserts.SoftAssert; + public class EditSampleSteps implements En { public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("M/d/yyyy"); public static final DateTimeFormatter DATE_FORMATTER_DE = @@ -316,22 +315,22 @@ public EditSampleSteps( Then( "I check that lab sample id match {string} specimen id from Demis message on Edit Sample page", (String specimen) -> { - switch (specimen) { - case "first": - softly.assertEquals( - webDriverHelpers.getValueFromWebElement(LAB_SAMPLE_ID_INPUT), - DemisApiService.specimenUUID, - "Sample id is incorrect"); - softly.assertAll(); - break; - case "second": - softly.assertEquals( - webDriverHelpers.getValueFromWebElement(LAB_SAMPLE_ID_INPUT), - DemisApiService.secondSpecimenUUID, - "Sample id is incorrect"); - softly.assertAll(); - break; - } + switch (specimen) { + case "first": + softly.assertEquals( + webDriverHelpers.getValueFromWebElement(LAB_SAMPLE_ID_INPUT), + DemisApiService.specimenUUID, + "Sample id is incorrect"); + softly.assertAll(); + break; + case "second": + softly.assertEquals( + webDriverHelpers.getValueFromWebElement(LAB_SAMPLE_ID_INPUT), + DemisApiService.secondSpecimenUUID, + "Sample id is incorrect"); + softly.assertAll(); + break; + } }); And( diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java index 32b794bd897..c665e9f7cbe 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java @@ -1,27 +1,5 @@ package org.sormas.e2etests.steps.web.application.survnet; -import cucumber.api.java8.En; -import lombok.extern.slf4j.Slf4j; -import org.jdom2.Attribute; -import org.jdom2.DataConversionException; -import org.jdom2.Document; -import org.jdom2.Element; -import org.jdom2.Namespace; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.helpers.parsers.XMLParser; -import org.sormas.e2etests.pages.application.NavBarPage; -import org.sormas.e2etests.steps.web.application.cases.CreateNewCaseSteps; -import org.sormas.e2etests.steps.web.application.events.EditEventSteps; -import org.sormas.e2etests.steps.web.application.persons.EditPersonSteps; -import org.testng.asserts.SoftAssert; - -import javax.inject.Inject; -import java.time.LocalDate; -import java.time.Period; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.List; - import static org.sormas.e2etests.helpers.SchemaValidator.XMLSchemaValidator.validateXMLSchema; import static org.sormas.e2etests.helpers.comparison.XMLComparison.compareXMLFiles; import static org.sormas.e2etests.helpers.comparison.XMLComparison.extractDiffNodes; @@ -41,6 +19,27 @@ import static org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps.randomVaccinationName; import static org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps.vaccination; +import cucumber.api.java8.En; +import java.time.LocalDate; +import java.time.Period; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; +import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import org.jdom2.Attribute; +import org.jdom2.DataConversionException; +import org.jdom2.Document; +import org.jdom2.Element; +import org.jdom2.Namespace; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.helpers.parsers.XMLParser; +import org.sormas.e2etests.pages.application.NavBarPage; +import org.sormas.e2etests.steps.web.application.cases.CreateNewCaseSteps; +import org.sormas.e2etests.steps.web.application.events.EditEventSteps; +import org.sormas.e2etests.steps.web.application.persons.EditPersonSteps; +import org.testng.asserts.SoftAssert; + @Slf4j public class SurvNetSteps implements En { @@ -710,71 +709,71 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { String mappedValue = null; switch (value) { - case"positive": - mappedValue = "20"; - break; - case"negative": - mappedValue = "0"; - break; - } + case "positive": + mappedValue = "20"; + break; + case "negative": + mappedValue = "0"; + break; + } switch (disease) { - case "diabetes": - softly.assertEquals( - getValueFromSpecificFieldByName(singleXmlFile, "Risk0005"), - mappedValue, - "Diabetes mapped value is incorrect!"); - softly.assertAll(); - break; - case "immunodeficiencyIncludingHiv": - softly.assertEquals( - getValueFromSpecificFieldByName(singleXmlFile, "Risk0008"), - mappedValue, - "Immunodeficiency mapped value is incorrect!"); - softly.assertAll(); - break; - case "chronicLiverDisease": - softly.assertEquals( - getValueFromSpecificFieldByName(singleXmlFile, "Risk0006"), - mappedValue, - "Liver disease mapped value is incorrect!"); - softly.assertAll(); - break; - case "malignancyChemotherapy": - softly.assertEquals( - getValueFromSpecificFieldByName(singleXmlFile, "Risk0011"), - mappedValue, - "Malignancy chemotherapy mapped value is incorrect!"); - softly.assertAll(); - break; - case "chronicPulmonaryDisease": - softly.assertEquals( - getValueFromSpecificFieldByName(singleXmlFile, "Risk0010"), - mappedValue, - "Chronic pulmonary disease mapped value is incorrect!"); - softly.assertAll(); - break; - case "chronicKidneyDisease": - softly.assertEquals( - getValueFromSpecificFieldByName(singleXmlFile, "Risk0009"), - mappedValue, - "Chronic kidney disease mapped value is incorrect!"); - softly.assertAll(); - break; - case "chronicNeurologicCondition": - softly.assertEquals( - getValueFromSpecificFieldByName(singleXmlFile, "Risk0007"), - mappedValue, - "Chronic neurologic condition mapped value is incorrect!"); - softly.assertAll(); - break; - case "cardiovascularDiseaseIncludingHypertension": - softly.assertEquals( - getValueFromSpecificFieldByName(singleXmlFile, "Risk0004"), - mappedValue, - "Cardiovascular disease mapped value is incorrect!"); - softly.assertAll(); - break; + case "diabetes": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0005"), + mappedValue, + "Diabetes mapped value is incorrect!"); + softly.assertAll(); + break; + case "immunodeficiencyIncludingHiv": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0008"), + mappedValue, + "Immunodeficiency mapped value is incorrect!"); + softly.assertAll(); + break; + case "chronicLiverDisease": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0006"), + mappedValue, + "Liver disease mapped value is incorrect!"); + softly.assertAll(); + break; + case "malignancyChemotherapy": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0011"), + mappedValue, + "Malignancy chemotherapy mapped value is incorrect!"); + softly.assertAll(); + break; + case "chronicPulmonaryDisease": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0010"), + mappedValue, + "Chronic pulmonary disease mapped value is incorrect!"); + softly.assertAll(); + break; + case "chronicKidneyDisease": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0009"), + mappedValue, + "Chronic kidney disease mapped value is incorrect!"); + softly.assertAll(); + break; + case "chronicNeurologicCondition": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0007"), + mappedValue, + "Chronic neurologic condition mapped value is incorrect!"); + softly.assertAll(); + break; + case "cardiovascularDiseaseIncludingHypertension": + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "Risk0004"), + mappedValue, + "Cardiovascular disease mapped value is incorrect!"); + softly.assertAll(); + break; } }); @@ -784,20 +783,19 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { switch (infectionOption) { case "Ambulant": softly.assertEquals( - getValueFromSpecificFieldByName(singleXmlFile, "P112Setting"), - "1000", - "Mapped value for Ambulance is incorrect"); + getValueFromSpecificFieldByName(singleXmlFile, "P112Setting"), + "1000", + "Mapped value for Ambulance is incorrect"); softly.assertAll(); break; case "Stationär": softly.assertEquals( - getValueFromSpecificFieldByName(singleXmlFile, "P112Setting"), - "2000", - "Mapped value for Stationär is incorrect "); + getValueFromSpecificFieldByName(singleXmlFile, "P112Setting"), + "2000", + "Mapped value for Stationär is incorrect "); softly.assertAll(); break; } - }); } diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Columns.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Columns.feature index f24a59b0b0b..12715b6b550 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Columns.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Columns.feature @@ -322,7 +322,7 @@ Scenario Outline: Sort column by date in Entries directory @tmsLink=SORQA-985 @env_s2s_2 Scenario Outline: S2S Order filters in Shared Folder - Given I log in as a Admin User + Given I log in as a S2S When I click on the Shares button from navbar And I click the header of column Then I check that error not appear for DE version @@ -350,7 +350,7 @@ Scenario Outline: S2S Order filters in Shared Folder @tmsLink=SORQA-985 @env_s2s_2 Scenario Outline: S2S Order filters in Shared Folder by date - Given I log in as a Admin User + Given I log in as a S2S When I click on the Shares button from navbar And I click the header of column Then I check that error not appear for DE version From 552c0a6f038e39f29bb711ebf848fa37e6a1d751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=A9=20Strysewske?= Date: Fri, 28 Jul 2023 13:53:45 +0200 Subject: [PATCH 134/174] #12361 - Check environment rights on sync --- .../api/environment/EnvironmentFacade.java | 4 ---- .../sormas/api/user/DtoViewAndEditRights.java | 4 ++++ .../sormas/app/rest/SynchronizeDataAsync.java | 17 +++++++++-------- .../environment/EnvironmentFacadeEjb.java | 5 ----- .../rest/resources/EnvironmentResource.java | 2 +- 5 files changed, 14 insertions(+), 18 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/environment/EnvironmentFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/environment/EnvironmentFacade.java index fa9d65dcfc3..112b71aadb0 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/environment/EnvironmentFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/environment/EnvironmentFacade.java @@ -1,8 +1,5 @@ package de.symeda.sormas.api.environment; -import java.util.Date; -import java.util.List; - import javax.ejb.Remote; import de.symeda.sormas.api.CoreFacade; @@ -10,5 +7,4 @@ @Remote public interface EnvironmentFacade extends CoreFacade { - List getAllEnvironmentsAfter(Date date); } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/user/DtoViewAndEditRights.java b/sormas-api/src/main/java/de/symeda/sormas/api/user/DtoViewAndEditRights.java index 7cc4f21f0a1..3165f675a78 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/user/DtoViewAndEditRights.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/user/DtoViewAndEditRights.java @@ -24,6 +24,7 @@ import de.symeda.sormas.api.caze.CaseDataDto; import de.symeda.sormas.api.clinicalcourse.ClinicalVisitDto; import de.symeda.sormas.api.contact.ContactDto; +import de.symeda.sormas.api.environment.EnvironmentDto; import de.symeda.sormas.api.event.EventDto; import de.symeda.sormas.api.event.EventParticipantDto; import de.symeda.sormas.api.immunization.ImmunizationDto; @@ -60,6 +61,9 @@ public class DtoViewAndEditRights { viewRights.put(ContactDto.class.getSimpleName(), UserRight.CONTACT_VIEW); editRights.put(ContactDto.class.getSimpleName(), UserRight.CONTACT_EDIT); + viewRights.put(EnvironmentDto.class.getSimpleName(), UserRight.ENVIRONMENT_VIEW); + editRights.put(EnvironmentDto.class.getSimpleName(), UserRight.ENVIRONMENT_EDIT); + viewRights.put(EventDto.class.getSimpleName(), UserRight.EVENT_VIEW); editRights.put(EventDto.class.getSimpleName(), UserRight.EVENT_EDIT); diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/SynchronizeDataAsync.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/SynchronizeDataAsync.java index 2d27931794c..fa1f59436fd 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/SynchronizeDataAsync.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/SynchronizeDataAsync.java @@ -294,6 +294,7 @@ public static boolean hasAnyUnsynchronizedData() { || DatabaseHelper.getSampleDao().isAnyModified() || DatabaseHelper.getSampleTestDao().isAnyModified() || DatabaseHelper.getAdditionalTestDao().isAnyModified() + || DatabaseHelper.getEnvironmentDao().isAnyModified() || DatabaseHelper.getTaskDao().isAnyModified() || DatabaseHelper.getVisitDao().isAnyModified() || DatabaseHelper.getWeeklyReportDao().isAnyModified() @@ -315,6 +316,7 @@ private void pushNewData() throws ServerCommunicationException, ServerConnection new SampleDtoHelper().pushEntities(true, syncCallbacks); new PathogenTestDtoHelper().pushEntities(true, syncCallbacks); new AdditionalTestDtoHelper().pushEntities(true, syncCallbacks); + new EnvironmentDtoHelper().pushEntities(true, syncCallbacks); new ContactDtoHelper().pushEntities(true, syncCallbacks); new VisitDtoHelper().pushEntities(true, syncCallbacks); new TaskDtoHelper().pushEntities(true, syncCallbacks); @@ -732,19 +734,18 @@ private void pullAndRemoveObsoleteUuidsSince(Date since) throws NoConnectionExce } syncCallbacks.ifPresent(c -> c.getLoadNextCallback().run()); - if (DtoUserRightsHelper.isViewAllowed(Environment.class)) { + if (DtoUserRightsHelper.isViewAllowed(EnvironmentDto.class)) { List environmentUuids = executeUuidCall(RetroProvider.getEnvironmentFacade().pullObsoleteUuidsSince(since != null ? since.getTime() : 0)); for (String environmentUuid : environmentUuids) { DatabaseHelper.getEnvironmentDao().deleteEnvironmentAndAllDependingEntities(environmentUuid); } + // Remove obsolete environments based on change date + List obsoleteEnvironments = DatabaseHelper.getEnvironmentDao().queryForObsolete(); + for (Environment obsoleteEnvironment : obsoleteEnvironments) { + DatabaseHelper.getEnvironmentDao().deleteEnvironmentAndAllDependingEntities(obsoleteEnvironment.getUuid()); + } } - // Remove obsolete environments based on change date - List obsoleteEnvironments = DatabaseHelper.getEnvironmentDao().queryForObsolete(); - for (Environment obsoleteEnvironment : obsoleteEnvironments) { - DatabaseHelper.getEnvironmentDao().deleteEnvironmentAndAllDependingEntities(obsoleteEnvironment.getUuid()); - } - syncCallbacks.ifPresent(c -> c.getLoadNextCallback().run()); // Tasks @@ -846,7 +847,7 @@ private void pushNewPullMissingAndDeleteInvalidData() List sampleUuids = viewAllowed ? executeUuidCall(RetroProvider.getSampleFacade().pullUuids()) : new ArrayList<>(); DatabaseHelper.getSampleDao().deleteInvalid(sampleUuids, syncCallbacks); //environments - viewAllowed = DtoUserRightsHelper.isViewAllowed(Environment.class); + viewAllowed = DtoUserRightsHelper.isViewAllowed(EnvironmentDto.class); List environmentUuids = viewAllowed ? executeUuidCall(RetroProvider.getEnvironmentFacade().pullUuids()) : new ArrayList<>(); DatabaseHelper.getEnvironmentDao().deleteInvalid(environmentUuids, syncCallbacks); // event participants diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/EnvironmentFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/EnvironmentFacadeEjb.java index 1e43b379076..5e1c4cfbc05 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/EnvironmentFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/EnvironmentFacadeEjb.java @@ -369,11 +369,6 @@ protected CoreEntityType getCoreEntityType() { return null; } - @Override - public List getAllEnvironmentsAfter(Date date) { - return service.getAllAfter(date).stream().map(r -> toDto(r)).collect(Collectors.toList()); - } - @Override public List getArchivedUuidsSince(Date since) { return null; diff --git a/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/EnvironmentResource.java b/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/EnvironmentResource.java index bdd02c1fac2..d6968e4e17a 100644 --- a/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/EnvironmentResource.java +++ b/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/EnvironmentResource.java @@ -25,7 +25,7 @@ public class EnvironmentResource extends EntityDtoResource { @GET @Path("/all/{since}") public List getAllEnvironments(@PathParam("since") long since) { - return FacadeProvider.getEnvironmentFacade().getAllEnvironmentsAfter(new Date(since)); + return FacadeProvider.getEnvironmentFacade().getAllAfter(new Date(since)); } @POST From f2ee9b3f792819f0462492c36100ce1a095a8e57 Mon Sep 17 00:00:00 2001 From: Levente Gal Date: Fri, 28 Jul 2023 15:34:36 +0300 Subject: [PATCH 135/174] #11464 Add bulk action progress window to all bulk actions except "Edit", "Archive" and "Delete" - fixed merge issues --- .../de/symeda/sormas/api/i18n/Strings.java | 1 + .../src/main/resources/strings.properties | 1 + .../sormas/ui/contact/ContactController.java | 24 ++++++--- .../sormas/ui/events/EventController.java | 29 +++++----- .../ui/events/EventGroupController.java | 25 ++++----- .../ExternalSurveillanceServiceGateway.java | 18 +++++-- .../symeda/sormas/ui/user/UserController.java | 54 ++++++++++--------- .../sormas/ui/utils/BulkOperationHandler.java | 6 +-- 8 files changed, 94 insertions(+), 64 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java index bba1a79f019..4bfe23c73f2 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java @@ -722,6 +722,7 @@ public interface Strings { String headingSimilarImmunization = "headingSimilarImmunization"; String headingSomeCasesNotDeleted = "headingSomeCasesNotDeleted"; String headingSomeCasesNotRestored = "headingSomeCasesNotRestored"; + String headingSomeContactsAlreadyInEvent = "headingSomeContactsAlreadyInEvent"; String headingSomeContactsNotDeleted = "headingSomeContactsNotDeleted"; String headingSomeContactsNotRestored = "headingSomeContactsNotRestored"; String headingSomeEventParticipantsNotDeleted = "headingSomeEventParticipantsNotDeleted"; diff --git a/sormas-api/src/main/resources/strings.properties b/sormas-api/src/main/resources/strings.properties index aa1b98094ad..c9d5e57fe53 100644 --- a/sormas-api/src/main/resources/strings.properties +++ b/sormas-api/src/main/resources/strings.properties @@ -805,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection: diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactController.java index f3146a32a83..3dedd5e9a25 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactController.java @@ -835,8 +835,14 @@ public void cancelFollowUpOfAllSelectedItems( if (Boolean.TRUE.equals(confirmed)) { String userName = UserProvider.getCurrent().getUserName(); - new BulkOperationHandler(Strings.messageFollowUpCanceled, Strings.messageFollowUpCanceledForSome) - .doBulkOperation(batch -> { + new BulkOperationHandler( + Strings.messageFollowUpCanceled, + null, + null, + null, + Strings.messageFollowUpCanceledForSome, + null, + null).doBulkOperation(batch -> { for (ContactIndexDto contact : batch) { if (!FollowUpStatus.NO_FOLLOW_UP.equals(contact.getFollowUpStatus()) && !FollowUpStatus.CANCELED.equals(contact.getFollowUpStatus())) { @@ -848,7 +854,7 @@ public void cancelFollowUpOfAllSelectedItems( } return batch.size(); - }, new ArrayList<>(selectedRows), bulkOperationCallback(caseUuid, contactGrid, null)); + }, new ArrayList<>(selectedRows), null, null, bulkOperationCallback(caseUuid, contactGrid, null)); } }); } @@ -875,8 +881,14 @@ public void setAllSelectedItemsToLostToFollowUp( if (Boolean.TRUE.equals(confirmed)) { String userName = UserProvider.getCurrent().getUserName(); - new BulkOperationHandler(Strings.messageFollowUpStatusChanged, Strings.messageFollowUpStatusChangedForSome) - .doBulkOperation(batch -> { + new BulkOperationHandler( + Strings.messageFollowUpStatusChanged, + null, + null, + null, + Strings.messageFollowUpStatusChangedForSome, + null, + null).doBulkOperation(batch -> { for (ContactIndexDto contact : batch) { if (contact.getFollowUpStatus() != FollowUpStatus.NO_FOLLOW_UP) { ContactDto contactDto = FacadeProvider.getContactFacade().getByUuid(contact.getUuid()); @@ -888,7 +900,7 @@ public void setAllSelectedItemsToLostToFollowUp( } return batch.size(); - }, new ArrayList<>(selectedRows), bulkOperationCallback(caseUuid, contactGrid, null)); + }, new ArrayList<>(selectedRows), null, null, bulkOperationCallback(caseUuid, contactGrid, null)); } }); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventController.java index 2d3f0d4e83c..50bce40c9d6 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventController.java @@ -328,28 +328,31 @@ private void linkContactsToEvent(EventReferenceDto eventReferenceDto, List byEventAndPersons = FacadeProvider.getEventParticipantFacade() .getByEventAndPersons(eventReferenceDto.getUuid(), new ArrayList<>(contactByPersonUuid.keySet())); - byEventAndPersons.forEach(eventParticipant -> contactByPersonUuid.remove(eventParticipant.getPerson().getUuid())); - if (contactByPersonUuid.isEmpty()) { - NotificationHelper.showNotification(I18nProperties.getString(Strings.messageAllContactsAlreadyInEvent), Type.HUMANIZED_MESSAGE, 10000); + List alreadyLinkedContacts = new ArrayList<>(); - return; - } + byEventAndPersons.forEach(eventParticipant -> { + String personUuid = eventParticipant.getPerson().getUuid(); + + alreadyLinkedContacts.add(contactByPersonUuid.get(personUuid)); + contactByPersonUuid.remove(personUuid); + }); //Create EventParticipants for the remaining contacts List remainingPersons = FacadeProvider.getPersonFacade().getByUuids(new ArrayList<>(contactByPersonUuid.keySet())); Map personByUuid = remainingPersons.stream().collect(Collectors.toMap(EntityDto::getUuid, Functions.identity())); - int contactsAlreadyLinkedToEvent = contacts.size() - contactByPersonUuid.size(); - String allLinkedMessage = contactsAlreadyLinkedToEvent == 0 - ? I18nProperties.getString(Strings.messageAllContactsLinkedToEvent) - : String.format(I18nProperties.getString(Strings.messageCountContactsAlreadyInEvent), contactsAlreadyLinkedToEvent); - UserReferenceDto currentUser = UserProvider.getCurrent().getUserReference(); - new BulkOperationHandler(allLinkedMessage, I18nProperties.getString(Strings.messageSomeContactsLinkedToEvent), true) - .doBulkOperation(batch -> { + new BulkOperationHandler( + Strings.messageAllContactsLinkedToEvent, + null, + Strings.headingSomeContactsAlreadyInEvent, + Strings.messageCountContactsAlreadyInEvent, + Strings.messageSomeContactsLinkedToEvent, + Strings.messageAllContactsAlreadyInEvent, + null).doBulkOperation(batch -> { batch.forEach(contactDataDto -> { EventParticipantDto ep = EventParticipantDto.buildFromPerson(personByUuid.get(contactDataDto.getPerson().getUuid()), eventReferenceDto, currentUser); @@ -357,7 +360,7 @@ private void linkContactsToEvent(EventReferenceDto eventReferenceDto, List(contactByPersonUuid.values()), callback); + }, new ArrayList<>(contacts), new ArrayList<>(contactByPersonUuid.values()), alreadyLinkedContacts, callback); } public void selectEvent(EventGroupReferenceDto eventGroupReference) { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventGroupController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventGroupController.java index 91709108e92..eda30492d3b 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventGroupController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventGroupController.java @@ -68,18 +68,19 @@ private static void linkEventsToGroup( Consumer> callback) { String messageEventsLinkedToGroup = eventReferences.size() > 1 ? Strings.messageEventsLinkedToGroup : Strings.messageEventLinkedToGroup; - new BulkOperationHandler(messageEventsLinkedToGroup, Strings.messageSomeEventsLinkedToGroup).doBulkOperation(batch -> { - FacadeProvider.getEventGroupFacade() - .linkEventsToGroups( - batch.stream().map(EventReferenceDto::getUuid).collect(Collectors.toList()), - Collections.singletonList(eventGroupReference.getUuid())); - FacadeProvider.getEventGroupFacade() - .notifyEventAddedToEventGroup( - eventGroupReference.getUuid(), - batch.stream().map(EventReferenceDto::getUuid).collect(Collectors.toSet())); - - return batch.size(); - }, new ArrayList<>(eventReferences), callback); + new BulkOperationHandler(messageEventsLinkedToGroup, null, null, null, Strings.messageSomeEventsLinkedToGroup, null, null) + .doBulkOperation(batch -> { + FacadeProvider.getEventGroupFacade() + .linkEventsToGroups( + batch.stream().map(EventReferenceDto::getUuid).collect(Collectors.toList()), + Collections.singletonList(eventGroupReference.getUuid())); + FacadeProvider.getEventGroupFacade() + .notifyEventAddedToEventGroup( + eventGroupReference.getUuid(), + batch.stream().map(EventReferenceDto::getUuid).collect(Collectors.toSet())); + + return batch.size(); + }, new ArrayList<>(eventReferences), null, null, callback); } public void create(EventReferenceDto eventReference) { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalsurveillanceservice/ExternalSurveillanceServiceGateway.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalsurveillanceservice/ExternalSurveillanceServiceGateway.java index 57e09ebcbbb..d86cbd0e5cf 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalsurveillanceservice/ExternalSurveillanceServiceGateway.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalsurveillanceservice/ExternalSurveillanceServiceGateway.java @@ -121,7 +121,12 @@ public static void sendCasesToExternalSurveillanceTool( ArrayList selectedCasesCpy = new ArrayList<>(selectedCases); new BulkOperationHandler( Strings.ExternalSurveillanceToolGateway_notificationEntriesSent, - Strings.ExternalSurveillanceToolGateway_notificationSomeEntriesSent).doBulkOperation(batch -> { + null, + null, + null, + Strings.ExternalSurveillanceToolGateway_notificationSomeEntriesSent, + null, + null).doBulkOperation(batch -> { try { FacadeProvider.getExternalSurveillanceToolFacade() .sendCases(batch.stream().map(CaseIndexDto::getUuid).collect(Collectors.toList())); @@ -130,7 +135,7 @@ public static void sendCasesToExternalSurveillanceTool( } return batch.size(); - }, selectedCasesCpy, callback); + }, selectedCasesCpy, null, null, callback); }, null, shouldConfirm, null); } @@ -143,7 +148,12 @@ public static void sendEventsToExternalSurveillanceTool( ArrayList selectedEventsCpy = new ArrayList<>(selectedEvents); new BulkOperationHandler( Strings.ExternalSurveillanceToolGateway_notificationEntriesSent, - Strings.ExternalSurveillanceToolGateway_notificationSomeEntriesSent).doBulkOperation(batch -> { + null, + null, + null, + Strings.ExternalSurveillanceToolGateway_notificationSomeEntriesSent, + null, + null).doBulkOperation(batch -> { try { FacadeProvider.getExternalSurveillanceToolFacade() .sendEvents(batch.stream().map(EventIndexDto::getUuid).collect(Collectors.toList())); @@ -152,7 +162,7 @@ public static void sendEventsToExternalSurveillanceTool( } return batch.size(); - }, selectedEventsCpy, callback); + }, selectedEventsCpy, null, null, callback); }, null, shouldConfirm, null); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserController.java index c0be526e89d..f8993620e4b 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserController.java @@ -367,19 +367,20 @@ public void enableAllSelectedItems(Collection selectedRows, UserGrid us return; } - new BulkOperationHandler(Strings.messageUsersEnabled, Strings.messageSomeUsersEnabled).doBulkOperation(batch -> { - List uuids = batch.stream().map(UserDto::getUuid).collect(Collectors.toList()); - FacadeProvider.getUserFacade().enableUsers(uuids); - - return batch.size(); - }, new ArrayList<>(selectedRows), remaining -> { - userGrid.reload(); - if (CollectionUtils.isNotEmpty(remaining)) { - userGrid.asMultiSelect().selectItems(remaining.toArray(new UserDto[0])); - } else { - overview(); - } - }); + new BulkOperationHandler(Strings.messageUsersEnabled, null, null, null, Strings.messageSomeUsersEnabled, null, null) + .doBulkOperation(batch -> { + List uuids = batch.stream().map(UserDto::getUuid).collect(Collectors.toList()); + FacadeProvider.getUserFacade().enableUsers(uuids); + + return batch.size(); + }, new ArrayList<>(selectedRows), null, null, remaining -> { + userGrid.reload(); + if (CollectionUtils.isNotEmpty(remaining)) { + userGrid.asMultiSelect().selectItems(remaining.toArray(new UserDto[0])); + } else { + overview(); + } + }); }); } } @@ -404,19 +405,20 @@ public void disableAllSelectedItems(Collection selectedRows, UserGrid u return; } - new BulkOperationHandler(Strings.messageUsersDisabled, Strings.messageSomeUsersDisabled).doBulkOperation(batch -> { - List uuids = batch.stream().map(UserDto::getUuid).collect(Collectors.toList()); - FacadeProvider.getUserFacade().disableUsers(uuids); - - return batch.size(); - }, new ArrayList<>(selectedRows), remaining -> { - userGrid.reload(); - if (CollectionUtils.isNotEmpty(remaining)) { - userGrid.asMultiSelect().selectItems(remaining.toArray(new UserDto[0])); - } else { - overview(); - } - }); + new BulkOperationHandler(Strings.messageUsersDisabled, null, null, null, Strings.messageSomeUsersDisabled, null, null) + .doBulkOperation(batch -> { + List uuids = batch.stream().map(UserDto::getUuid).collect(Collectors.toList()); + FacadeProvider.getUserFacade().disableUsers(uuids); + + return batch.size(); + }, new ArrayList<>(selectedRows), null, null, remaining -> { + userGrid.reload(); + if (CollectionUtils.isNotEmpty(remaining)) { + userGrid.asMultiSelect().selectItems(remaining.toArray(new UserDto[0])); + } else { + overview(); + } + }); }); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/BulkOperationHandler.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/BulkOperationHandler.java index eb7fcfe21c8..09c4b5a89c8 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/BulkOperationHandler.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/BulkOperationHandler.java @@ -55,8 +55,6 @@ public class BulkOperationHandler { private final String noEligibleEntityMessageProperty; private final String infoBulkProcessFinishedWithSkipsProperty; - private boolean messagesTranslated; - public BulkOperationHandler( String allEntriesProcessedMessageProperty, String ineligibleEntriesNotProcessedMessageProperty, @@ -120,7 +118,9 @@ public void doBulkOperation( String description = getErrorDescription( selectedIneligibleEntries.stream().map(HasUuid::getUuid).collect(Collectors.toList()), I18nProperties.getString(countEntriesNotProcessedMessageProperty), - I18nProperties.getString(ineligibleEntriesNotProcessedMessageProperty)); + ineligibleEntriesNotProcessedMessageProperty != null + ? I18nProperties.getString(ineligibleEntriesNotProcessedMessageProperty) + : ""); Window response = VaadinUiUtil.showSimplePopupWindow(I18nProperties.getString(headingSomeEntitiesNotProcessed), description, ContentMode.HTML); From b90131a380dce4ba7dd67f7ef106dac6e1817e67 Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Tue, 1 Aug 2023 12:22:08 +0200 Subject: [PATCH 136/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. --- .../services/api/demis/DemisApiService.java | 34 ++-- .../steps/api/demisSteps/DemisSteps.java | 155 ++++++++---------- .../features/sanity/web/DemisWeb.feature | 28 +++- 3 files changed, 115 insertions(+), 102 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java index c0cfbe3c275..5bdea075db8 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java @@ -17,26 +17,23 @@ */ package org.sormas.e2etests.entities.services.api.demis; -import static org.sormas.e2etests.steps.BaseSteps.locale; - -import java.net.SocketTimeoutException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.UUID; -import javax.inject.Inject; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; -import okhttp3.MediaType; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; +import okhttp3.*; import org.json.simple.JSONObject; import org.json.simple.JSONValue; import org.sormas.e2etests.envconfig.dto.demis.DemisData; import org.sormas.e2etests.envconfig.manager.RunningConfiguration; import org.sormas.e2etests.helpers.api.demis.okhttpclient.SormasOkHttpClient; +import javax.inject.Inject; +import java.net.SocketTimeoutException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.UUID; + +import static org.sormas.e2etests.steps.BaseSteps.locale; + @Slf4j public class DemisApiService { @@ -288,6 +285,19 @@ public String prepareLabNotificationFileWithMultiplePathogenOneSample( return json; } + public String prepareLabNotificationFileForPhysicianReport( + String patientFirstName, String patientLastName) { + DemisData demisData = runningConfiguration.getDemisData(locale); + String file = "src/main/resources/demisJsonTemplates/labNotificationTemplatePhysicianReport.json"; + String json = readFileAsString(file); + json = json.replace("", UUID.randomUUID().toString()); + json = json.replace("\"\"", "\"" + demisData.getPostalCode() + "\""); + json = json.replace("\"\"", "\"" + patientLastName + "\""); + json = json.replace("\"\"", "\"" + patientFirstName + "\""); + return json; + } + + /** Delete method once we start adding tests */ @SneakyThrows public String loginRequest() { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java index 0f499c4621c..aa4835f5137 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java @@ -1,111 +1,53 @@ package org.sormas.e2etests.steps.api.demisSteps; +import com.github.javafaker.Faker; +import cucumber.api.java8.En; +import lombok.extern.slf4j.Slf4j; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.sormas.e2etests.entities.pojo.web.Event; +import org.sormas.e2etests.entities.services.EventService; +import org.sormas.e2etests.entities.services.api.demis.DemisApiService; +import org.sormas.e2etests.envconfig.dto.demis.DemisData; +import org.sormas.e2etests.envconfig.manager.RunningConfiguration; +import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.steps.BaseSteps; +import org.sormas.e2etests.steps.web.application.messages.MessagesTableViewHeaders; +import org.testng.Assert; +import org.testng.asserts.SoftAssert; + +import javax.inject.Inject; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.PERSON_ID_NAME_CONTACT_INFORMATION_LIKE_INPUT; -import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.DATE_OF_REPORT_INPUT; -import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.FIRST_NAME_INPUT; -import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.LAST_NAME_INPUT; import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.PLACE_OF_STAY_DISTRICT_COMBOBOX; import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.PLACE_OF_STAY_REGION_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.ACTION_CANCEL; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.DISTRICT_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.PLACE_OF_STAY_OPTIONS; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.REGION_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.SAVE_POPUP_CONTENT; +import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.*; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.*; import static org.sormas.e2etests.pages.application.cases.EditContactsPage.RESPONSIBLE_DISTRICT_COMBOBOX; import static org.sormas.e2etests.pages.application.cases.EditContactsPage.RESPONSIBLE_REGION_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.EditContactsPage.getContactFirstAndLastName; +import static org.sormas.e2etests.pages.application.cases.EditContactsPage.*; import static org.sormas.e2etests.pages.application.contacts.ContactDirectoryPage.PERSON_LIKE_SEARCH_INPUT; import static org.sormas.e2etests.pages.application.entries.CreateNewTravelEntryPage.CREATE_NEW_CASE_RADIOBUTTON_DE; import static org.sormas.e2etests.pages.application.entries.CreateNewTravelEntryPage.CREATE_NEW_CONTACT_RADIOBUTTON_DE; import static org.sormas.e2etests.pages.application.entries.TravelEntryPage.NEW_PERSON_RADIOBUTTON_DE; import static org.sormas.e2etests.pages.application.entries.TravelEntryPage.PICK_OR_CREATE_PERSON_HEADER_DE; -import static org.sormas.e2etests.pages.application.events.CreateNewEventPage.EVENT_DISTRICT; -import static org.sormas.e2etests.pages.application.events.CreateNewEventPage.EVENT_REGION; -import static org.sormas.e2etests.pages.application.events.CreateNewEventPage.NEW_EVENT_CREATED_DE_MESSAGE; -import static org.sormas.e2etests.pages.application.events.CreateNewEventPage.NEW_EVENT_RADIOBUTTON_DE_MESSAGE; -import static org.sormas.e2etests.pages.application.events.CreateNewEventPage.TITLE_INPUT; +import static org.sormas.e2etests.pages.application.events.CreateNewEventPage.*; import static org.sormas.e2etests.pages.application.events.EventDirectoryPage.CHOOSE_OR_CREATE_EVENT_HEADER_DE; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.ALL_QUICK_FILTER_COUNTER; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.APPLY_FILTER_MESSAGE; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CHOOSE_OR_CREATE_ENTRY_HEADER; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CREATE_A_NEW_CASE_WITH_POSITIVE_TEST_CONTACT_HEADER_DE; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CREATE_A_NEW_CASE_WITH_POSITIVE_TEST_EVENT_PARTICIPANT_HEADER_DE; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CREATE_NEW_EVENT_PARTICIPANT_RADIOBUTTON_DE; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CREATE_NEW_PERSON_RADIOBUTTON_DE; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CREATE_NEW_SAMPLE_CHECKBOX; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.FIRST_PATHOGEN_LABORATORY_INPUT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.FORWARDED_QUICK_FILTER_BUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.FORWARDED_QUICK_FILTER_COUNTER; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.LABORATORY_DETAILS_INPUT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.LABORATORY_INPUT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGES_DETAILED_COLUMN_HEADERS; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGES_DETAILED_TABLE_ROWS; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGES_TABLE_DATA; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGE_DATE_FROM_INPUT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGE_EYE_ICON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGE_POPUP_HEADER; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGE_TIME_FROM_COMBOBOX; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGE_UUID_TEXT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MULTIPLE_SAMPLES_HEADER; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_CASE_FORM_DISEASE_VARIANT_INPUT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_FIRST_PATHOGEN_DISEASE_VARIANT_INPUT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_FIRST_PATHOGEN_LABORATORY_NAME; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_FIRST_PATHOGEN_TEST_TYPE_INPUT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_LABORATORY_NAME; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_SECOND_PATHOGEN_DISEASE_VARIANT_INPUT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_SECOND_PATHOGEN_LABORATORY_NAME; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_SECOND_PATHOGEN_TEST_TYPE_INPUT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.PATIENT_BIRTHDAY_FROM_INPUT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.PATIENT_BIRTHDAY_TO_INPUT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.POPUP_CONFIRM_BUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.POPUP_WINDOW_SAVE_AND_OPEN_CASE_BUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.PROCESSED_QUICK_FILTER_BUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.PROCESSED_QUICK_FILTER_COUNTER; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.RELATED_FORWARDED_MESSAGE_HEADER; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.SAVE_POPUP_CONTENT_SECOND_BUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.SEARCH_MESSAGE_INPUT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.UNCLEAR_QUICK_FILTER_BUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.UNCLEAR_QUICK_FILTER_COUNTER; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.UNPROCESSED_QUICK_FILTER_BUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.UNPROCESSED_QUICK_FILTER_COUNTER; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.UPDATE_THE_DISEASE_VARIANT_HEADER; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.VERARBEITEN_BUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.checkMappedValueSelector; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.*; import static org.sormas.e2etests.pages.application.persons.PersonDirectoryPage.RESET_FILTERS_BUTTON; import static org.sormas.e2etests.pages.application.samples.CreateNewSamplePage.SAVE_SAMPLE_BUTTON; import static org.sormas.e2etests.pages.application.samples.CreateNewSamplePage.TYPE_OF_TEST_INPUT; import static org.sormas.e2etests.pages.application.samples.EditSamplePage.PCR_TEST_SPECIFICATION_INPUT; import static org.sormas.e2etests.steps.BaseSteps.locale; -import com.github.javafaker.Faker; -import cucumber.api.java8.En; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import javax.inject.Inject; -import lombok.extern.slf4j.Slf4j; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; -import org.sormas.e2etests.entities.pojo.web.Event; -import org.sormas.e2etests.entities.services.EventService; -import org.sormas.e2etests.entities.services.api.demis.DemisApiService; -import org.sormas.e2etests.envconfig.dto.demis.DemisData; -import org.sormas.e2etests.envconfig.manager.RunningConfiguration; -import org.sormas.e2etests.helpers.WebDriverHelpers; -import org.sormas.e2etests.steps.BaseSteps; -import org.sormas.e2etests.steps.web.application.messages.MessagesTableViewHeaders; -import org.testng.Assert; -import org.testng.asserts.SoftAssert; - @Slf4j public class DemisSteps implements En { @@ -988,6 +930,41 @@ public DemisSteps( break; } }); + + When( + "^I create and send Laboratory Notification for physician report$", + () -> { + patientFirstName = faker.name().firstName(); + patientLastName = faker.name().lastName(); + String json = demisApiService.prepareLabNotificationFileForPhysicianReport(patientFirstName, patientLastName); + + Assert.assertTrue(demisApiService.sendLabRequest(json, loginToken), "Failed to send laboratory request"); + + }); + + And( + "^I click on \"([^\"]*)\" button in new physician report form while processing a message$", + (String option) -> { + switch (option) { + case "save and open case": + webDriverHelpers.waitUntilElementIsVisibleAndClickable(POPUP_WINDOW_SAVE_AND_OPEN_PHYSICIAN_REPORT_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(POPUP_WINDOW_SAVE_AND_OPEN_PHYSICIAN_REPORT_BUTTON); + break; + case "cancel": + webDriverHelpers.waitUntilElementIsVisibleAndClickable(POPUP_WINDOW_CANCEL_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(POPUP_WINDOW_CANCEL_BUTTON); + break; + case "back": + webDriverHelpers.waitUntilElementIsVisibleAndClickable(POPUP_WINDOW_BACK_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(POPUP_WINDOW_BACK_BUTTON); + break; + case "save": + webDriverHelpers.waitUntilElementIsVisibleAndClickable(POPUP_WINDOW_SAVE_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(POPUP_WINDOW_SAVE_BUTTON); + webDriverHelpers.waitUntilIdentifiedElementIsPresent(UUID_INPUT); + break; + } + }); } private List> getTableRowsData() { diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index 1519f979721..b448f2e1565 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -603,4 +603,30 @@ Scenario: Create and send laboratory request via Demis And I check if external message window appears and close it Then I click on the Messages button from navbar And I filter by last created person via API in Messages Directory - And I verify that status for result 1 is set to processed in Message Directory page \ No newline at end of file + And I verify that status for result 1 is set to processed in Message Directory page + + @tmsLink=SORQA-1024 @env_d2s @LoginKeycloak + Scenario: Demis - Process a Physician Report + Given API : Login to DEMIS server + When I create and send Laboratory Notification for physician report + And I log in as a Admin User + And I click on the Messages button from navbar + And I click on fetch messages button + And I filter by last created person via API in Messages Directory + And I click on Verarbeiten button in Messages Directory + And I pick a new person in Pick or create person popup during case creation for DE + And I fill only mandatory fields to convert laboratory message into a case for DE + And I click on "save" button in new physician report form while processing a message + And I click next button while processing a DEMIS LabMessage + And I click next button while processing a DEMIS LabMessage + And I click next button while processing a DEMIS LabMessage + And I click on "save and open" button in new physician report form while processing a message + Then I check if there is no displayed sample result on Edit case page + And I click on Display associated external messages button from Reports side component + And I check if external message window appears and close it + Then I click on the Messages button from navbar + And I filter by last created person via API in Messages Directory + And I verify that status for result 1 is set to processed in Message Directory page + And I select "Physician's report" type of message in Message Directory page + And I click on the APPLY FILTERS button + And I check that all displayed messages have "Physician's report" in grid Message Directory Type column \ No newline at end of file From cd975733dc8d0c2fc1ebe8c15d3d7388ac9ca09f Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Tue, 1 Aug 2023 12:34:30 +0200 Subject: [PATCH 137/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. New steps have been added. --- .../messages/MessagesDirectoryPage.java | 7 ++ .../steps/api/demisSteps/DemisSteps.java | 13 ++++ .../messages/MessagesDirectorySteps.java | 69 +++++++------------ 3 files changed, 43 insertions(+), 46 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java index 27c7e31ebe7..0c2b343c2d8 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java @@ -147,4 +147,11 @@ public static By getProcessStatusByIndex(int index) { By.xpath("(//div[contains(@id, 'testType')]//input)[1]"); public static final By NEW_SAMPLE_FORM_SECOND_PATHOGEN_TEST_TYPE_INPUT = By.xpath("(//div[contains(@id, 'testType')]//input)[2]"); + public static final By POPUP_WINDOW_SAVE_AND_OPEN_PHYSICIAN_REPORT_BUTTON = + By.cssSelector("#actionSaveAndOpenCase"); + public static final By POPUP_WINDOW_BACK_BUTTON = By.id("actionBack"); + public static final By NEXT_BUTTON = By.id("actionNext"); + public static final By CASE_SAVED_POPUP_DE = By.cssSelector(".warning .v-Notification-caption"); + public static final By TYPE_OF_MESSAGE_COMBOBOX = By.cssSelector("[id='type'] [class='v-filterselect-button']"); + public static final By GRID_RESULTS_TYPE = By.cssSelector("tr:nth-of-type(1) > td:nth-of-type(3)"); } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java index aa4835f5137..d48d9464240 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java @@ -965,6 +965,19 @@ public DemisSteps( break; } }); + + And( + "^I click next button while processing a DEMIS LabMessage$", + () -> { + if (webDriverHelpers.isElementVisibleWithTimeout(CASE_SAVED_POPUP_DE, 5)) { + webDriverHelpers.clickOnWebElementBySelector(CASE_SAVED_POPUP_DE); + } + webDriverHelpers.waitUntilIdentifiedElementIsPresent(NEXT_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(NEXT_BUTTON); + webDriverHelpers.waitUntilIdentifiedElementIsPresent(CASE_SAVED_POPUP_DE); + webDriverHelpers.clickOnWebElementBySelector(CASE_SAVED_POPUP_DE); + TimeUnit.SECONDS.sleep(2); + }); } private List> getTableRowsData() { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java index b64d076a611..52be54415c2 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java @@ -1,52 +1,6 @@ package org.sormas.e2etests.steps.web.application.messages; -import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.ACTION_CONFIRM_POPUP_BUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.ACTION_YES_BUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CLOSE_POPUP; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CREATE_NEW_CASE_POPUP_WINDOW_DE; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CREATE_NEW_SAMPLE_POPUP_WINDOW_DE; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.FETCH_MESSAGES_BUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.FETCH_MESSAGES_NULL_DATE; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.FETCH_MESSAGES_NULL_TIME_COMBOBOX; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.FIRST_RECORD_DISEASE_VARIANT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.FIRST_TIME_FETCH_MESSAGE_POPUP; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.FORWARDED_MESSAGE_COUNTER; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.GET_NEW_MESSAGES_POPUP; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MARK_AS_FORWARDED_BUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MARK_AS_UNCLEAR_BUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGE_DELETE_BUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGE_DIRECTORY_HEADER_DE; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGE_UUID_TEXT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_CASE_EMAIL_ADDRESS_INPUT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_CASE_PHONE_NUMBER_INPUT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_DATE_OF_REPORT_INPUT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_SPECIMEN_CONDITION_INPUT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_TESTED_DISEASE_INPUT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_TEST_RESULT_INPUT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_TEST_RESULT_VERIFIED_RADIOBUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_TEST_RESULT_VERIFIED_SELECTED_VALUE; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NO_NEW_REPORTS_POPUP; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.PATHOGEN_DETECTION_REPORTING_PROCESS_HEADER_DE; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.POPUP_CONFIRM_BUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.POPUP_WINDOW_CANCEL_BUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.POPUP_WINDOW_DISCARD_BUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.POPUP_WINDOW_SAVE_AND_OPEN_CASE_BUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.POPUP_WINDOW_SAVE_BUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.RESET_FILTER_BUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.SEARCH_MESSAGE_INPUT; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.TOTAL_MESSAGE_COUNTER; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.UNCLEAR_MESSAGE_COUNTER; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.UPDATE_CASE_DISEASE_VARIANT_CONFIRM_BUTTON; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.getProcessMessageButtonByIndex; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.getProcessStatusByIndex; - import cucumber.api.java8.En; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; -import javax.inject.Inject; import lombok.extern.slf4j.Slf4j; import org.openqa.selenium.Keys; import org.openqa.selenium.interactions.Actions; @@ -56,6 +10,16 @@ import org.testng.Assert; import org.testng.asserts.SoftAssert; +import javax.inject.Inject; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.ACTION_CONFIRM_POPUP_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.*; + @Slf4j public class MessagesDirectorySteps implements En { @@ -379,5 +343,18 @@ public MessagesDirectorySteps( "Disease variant is not empty"); softly.assertAll(); }); + + And( + "^I select \"([^\"]*)\" type of message in Message Directory page$", + (String typeOfMessage) -> { + webDriverHelpers.waitUntilIdentifiedElementIsPresent(TYPE_OF_MESSAGE_COMBOBOX); + webDriverHelpers.selectFromCombobox(TYPE_OF_MESSAGE_COMBOBOX, typeOfMessage); + }); + + And( + "^I check that all displayed messages have \"([^\"]*)\" in grid Message Directory Type column$", + (String type) -> { + webDriverHelpers.waitUntilAListOfElementsHasText(GRID_RESULTS_TYPE, type); + }); } } From 61f19cd91c251c22544039e3f04b7efbc044bc5a Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Tue, 1 Aug 2023 12:37:45 +0200 Subject: [PATCH 138/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. New steps have been added. --- .../application/messages/MessagesDirectorySteps.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java index 52be54415c2..154e4c844ab 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java @@ -18,6 +18,7 @@ import java.util.concurrent.TimeUnit; import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.ACTION_CONFIRM_POPUP_BUTTON; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.SAMPLES_CARD_DATE_OF_COLLECTED_SAMPLE; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.*; @Slf4j @@ -356,5 +357,15 @@ public MessagesDirectorySteps( (String type) -> { webDriverHelpers.waitUntilAListOfElementsHasText(GRID_RESULTS_TYPE, type); }); + + Then( + "^I check if there is no displayed sample result on Edit case page$", + () -> { + softly.assertFalse( + webDriverHelpers.isElementPresent(SAMPLES_CARD_DATE_OF_COLLECTED_SAMPLE), + "Element is present!"); + softly.assertAll(); + + }); } } From 16c4a15daf36731105bbd613091fa07f19ebcd5d Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Tue, 1 Aug 2023 13:02:24 +0200 Subject: [PATCH 139/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. New lab notification template for physician has been added. --- ...abNotificationTemplatePhysicianReport.json | 474 ++++++++++++++++++ 1 file changed, 474 insertions(+) create mode 100644 sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationTemplatePhysicianReport.json diff --git a/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationTemplatePhysicianReport.json b/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationTemplatePhysicianReport.json new file mode 100644 index 00000000000..3b51c31edae --- /dev/null +++ b/sormas-e2e-tests/src/main/resources/demisJsonTemplates/labNotificationTemplatePhysicianReport.json @@ -0,0 +1,474 @@ +{ + "resourceType": "Bundle", + "id": "098f6bcd-4621-3373-8ade-4e832627b4f6", + "meta": { + "lastUpdated": "2021-03-04T12:00:00.000+01:00", + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotificationBundleDisease" + ] + }, + "identifier": { + "system": "https://demis.rki.de/fhir/NamingSystem/NotificationBundleId", + "value": "f6f4061a-1bdd-31c0-8d81-09b39f581270" + }, + "type": "document", + "timestamp": "2021-03-04T12:00:00.000+01:00", + "entry": [ + { + "fullUrl": "https://demis.rki.de/fhir/Composition/9f0a1336-3ac2-3a31-bfff-b8233c214452", + "resource": { + "resourceType": "Composition", + "id": "9f0a1336-3ac2-3a31-bfff-b8233c214452", + "meta": { + "lastUpdated": "2021-03-04T12:00:00.000+01:00", + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotificationDiseaseCVDD" + ] + }, + "identifier": { + "system": "https://demis.rki.de/fhir/NamingSystem/NotificationId", + "value": "" + }, + "status": "final", + "type": { + "coding": [ + { + "system": "http://loinc.org", + "code": "34782-3", + "display": "Infectious disease Note" + } + ] + }, + "category": [ + { + "coding": [ + { + "system": "https://demis.rki.de/fhir/CodeSystem/notificationType", + "code": "6.1_2", + "display": "Meldung gemäß §6 Absatz 1, 2" + } + ] + } + ], + "subject": { + "reference": "Patient/ac163863-fefa-3ce2-8511-7a4150d6ad43" + }, + "date": "2021-03-04T01:00:00+01:00", + "author": [ + { + "reference": "PractitionerRole/6373194f-4d06-382a-a67d-e3c7da243c30" + } + ], + "title": "Meldung gemäß §6 Absatz 1, 2 IfSG", + "section": [ + { + "title": "Diagnose", + "code": { + "coding": [ + { + "system": "https://demis.rki.de/fhir/CodeSystem/sectionCode", + "code": "diagnosis", + "display": "Diagnose" + } + ] + }, + "entry": [ + { + "reference": "Condition/cc86fc62-11af-3411-8b5e-6b2202206ec4" + } + ] + }, + { + "title": "Meldetatbestandsübergreifende klinische und epidemiologische Angaben", + "code": { + "coding": [ + { + "system": "https://demis.rki.de/fhir/CodeSystem/sectionCode", + "code": "generalClinAndEpiInformation", + "display": "Meldetatbestandsübergreifende klinische und epidemiologische Angaben" + } + ] + }, + "entry": [ + { + "reference": "QuestionnaireResponse/2f0c6b36-6421-35a8-8ea1-0e013db39410" + } + ] + }, + { + "title": "Meldetatbestandsspezifische klinische und epidemiologische Angaben", + "code": { + "coding": [ + { + "system": "https://demis.rki.de/fhir/CodeSystem/sectionCode", + "code": "specificClinAndEpiInformation", + "display": "Meldetatbestandsspezifische klinische und epidemiologische Angaben" + } + ] + }, + "entry": [ + { + "reference": "QuestionnaireResponse/146e5ced-db63-36e0-b8d3-85fa94218d8b" + } + ] + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Patient/ac163863-fefa-3ce2-8511-7a4150d6ad43", + "resource": { + "resourceType": "Patient", + "id": "ac163863-fefa-3ce2-8511-7a4150d6ad43", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotifiedPerson" + ] + }, + "name": [ + { + "use": "official", + "family": "", + "given": [ + "" + ] + } + ], + "gender": "female", + "birthDate": "1991-12-30", + "address": [ + { + "extension": [ + { + "url": "https://demis.rki.de/fhir/StructureDefinition/AddressUse", + "valueCoding": { + "system": "https://demis.rki.de/fhir/CodeSystem/addressUse", + "code": "primary" + } + } + ], + "line": [ + "Heerstr. 1" + ], + "city": "Hamburg", + "postalCode": "", + "country": "20422" + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Condition/cc86fc62-11af-3411-8b5e-6b2202206ec4", + "resource": { + "resourceType": "Condition", + "id": "cc86fc62-11af-3411-8b5e-6b2202206ec4", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/DiseaseCVDD" + ] + }, + "verificationStatus": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/condition-ver-status", + "code": "confirmed" + } + ] + }, + "code": { + "coding": [ + { + "system": "https://demis.rki.de/fhir/CodeSystem/notificationDiseaseCategory", + "code": "cvdd", + "display": "Coronavirus-Krankheit-2019 (COVID-19)" + } + ] + }, + "subject": { + "reference": "Patient/ac163863-fefa-3ce2-8511-7a4150d6ad43" + }, + "recordedDate": "2021-03-04" + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Organization/7b1cb8d3-f4bb-3cf6-8c0e-01e6657a13ea", + "resource": { + "resourceType": "Organization", + "id": "7b1cb8d3-f4bb-3cf6-8c0e-01e6657a13ea", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotifierFacility" + ] + }, + "identifier": [ + { + "system": "https://fhir.kbv.de/NamingSystem/KBV_NS_Base_BSNR", + "value": "987654300" + } + ], + "type": [ + { + "coding": [ + { + "system": "https://demis.rki.de/fhir/CodeSystem/organizationType", + "code": "hospital" + } + ] + } + ], + "name": "Sankt Gertrauden Krankenhaus", + "telecom": [ + { + "system": "phone", + "value": "309876543210", + "use": "work" + } + ], + "address": [ + { + "line": [ + "Dingsweg 321" + ], + "city": "Hamburg", + "postalCode": "", + "country": "20422" + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/PractitionerRole/6373194f-4d06-382a-a67d-e3c7da243c30", + "resource": { + "resourceType": "PractitionerRole", + "id": "6373194f-4d06-382a-a67d-e3c7da243c30", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/NotifierRole" + ] + }, + "organization": { + "reference": "Organization/7b1cb8d3-f4bb-3cf6-8c0e-01e6657a13ea" + } + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/Encounter/cf424cfb-8809-3b51-8ab2-d8bf979cbe8d", + "resource": { + "resourceType": "Encounter", + "id": "cf424cfb-8809-3b51-8ab2-d8bf979cbe8d", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/Hospitalization" + ] + }, + "status": "in-progress", + "class": { + "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode", + "code": "IMP", + "display": "inpatient encounter" + }, + "serviceType": { + "coding": [ + { + "system": "https://demis.rki.de/fhir/CodeSystem/hospitalizationServiceType", + "code": "0800", + "display": "Pneumologie" + } + ] + }, + "subject": { + "reference": "Patient/ac163863-fefa-3ce2-8511-7a4150d6ad43" + }, + "period": { + "start": "2021-03-04" + }, + "serviceProvider": { + "reference": "Organization/7b1cb8d3-f4bb-3cf6-8c0e-01e6657a13ea" + } + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/QuestionnaireResponse/2f0c6b36-6421-35a8-8ea1-0e013db39410", + "resource": { + "resourceType": "QuestionnaireResponse", + "id": "2f0c6b36-6421-35a8-8ea1-0e013db39410", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/DiseaseInformationCommon" + ] + }, + "questionnaire": "https://demis.rki.de/fhir/Questionnaire/DiseaseQuestionsCommon", + "status": "completed", + "subject": { + "reference": "Patient/ac163863-fefa-3ce2-8511-7a4150d6ad43" + }, + "item": [ + { + "linkId": "isDead", + "answer": [ + { + "valueCoding": { + "system": "https://demis.rki.de/fhir/CodeSystem/yesOrNoAnswer", + "code": "no", + "display": "Nein" + } + } + ] + }, + { + "linkId": "militaryAffiliation", + "answer": [ + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", + "code": "NASK", + "display": "not asked" + } + } + ] + }, + { + "linkId": "labSpecimenTaken", + "answer": [ + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", + "code": "NASK", + "display": "not asked" + } + } + ] + }, + { + "linkId": "hospitalized", + "answer": [ + { + "valueCoding": { + "system": "https://demis.rki.de/fhir/CodeSystem/yesOrNoAnswer", + "code": "yes", + "display": "Ja" + }, + "item": [ + { + "linkId": "hospitalizedGroup", + "item": [ + { + "linkId": "hospitalizedEncounter", + "answer": [ + { + "valueReference": { + "reference": "Encounter/cf424cfb-8809-3b51-8ab2-d8bf979cbe8d" + } + } + ] + } + ] + } + ] + } + ] + }, + { + "linkId": "infectProtectFacility", + "answer": [ + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", + "code": "NASK", + "display": "not asked" + } + } + ] + }, + { + "linkId": "placeExposure", + "answer": [ + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", + "code": "NASK", + "display": "not asked" + } + } + ] + }, + { + "linkId": "organDonation", + "answer": [ + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", + "code": "NASK", + "display": "not asked" + } + } + ] + }, + { + "linkId": "additionalInformation", + "answer": [ + { + "valueString": "Die Meldungsgenerierung erfolgte automatisch über den Aufnahmedatensatz gem. §301 SGB V. Nicht alle erforderlichen Informationen konnten daher erhoben werden." + } + ] + } + ] + } + }, + { + "fullUrl": "https://demis.rki.de/fhir/QuestionnaireResponse/146e5ced-db63-36e0-b8d3-85fa94218d8b", + "resource": { + "resourceType": "QuestionnaireResponse", + "id": "146e5ced-db63-36e0-b8d3-85fa94218d8b", + "meta": { + "profile": [ + "https://demis.rki.de/fhir/StructureDefinition/DiseaseInformationCVDD" + ] + }, + "questionnaire": "https://demis.rki.de/fhir/Questionnaire/DiseaseQuestionsCVDD", + "status": "completed", + "subject": { + "reference": "Patient/ac163863-fefa-3ce2-8511-7a4150d6ad43" + }, + "item": [ + { + "linkId": "infectionSource", + "answer": [ + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", + "code": "NASK", + "display": "not asked" + } + } + ] + }, + { + "linkId": "infectionEnvironmentSetting", + "answer": [ + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", + "code": "NASK", + "display": "not asked" + } + } + ] + }, + { + "linkId": "immunization", + "answer": [ + { + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor", + "code": "NASK", + "display": "not asked" + } + } + ] + } + ] + } + } + ] +} \ No newline at end of file From 6257bb2fcc4efe002e50fbf68252432b372dff1f Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Tue, 1 Aug 2023 13:19:18 +0200 Subject: [PATCH 140/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. Changes in clicking next button method --- .../pages/application/messages/MessagesDirectoryPage.java | 2 +- .../org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java index 0c2b343c2d8..15a6daa73e5 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java @@ -148,7 +148,7 @@ public static By getProcessStatusByIndex(int index) { public static final By NEW_SAMPLE_FORM_SECOND_PATHOGEN_TEST_TYPE_INPUT = By.xpath("(//div[contains(@id, 'testType')]//input)[2]"); public static final By POPUP_WINDOW_SAVE_AND_OPEN_PHYSICIAN_REPORT_BUTTON = - By.cssSelector("#actionSaveAndOpenCase"); + By.id("actionSaveAndOpenCase"); public static final By POPUP_WINDOW_BACK_BUTTON = By.id("actionBack"); public static final By NEXT_BUTTON = By.id("actionNext"); public static final By CASE_SAVED_POPUP_DE = By.cssSelector(".warning .v-Notification-caption"); diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java index d48d9464240..7ed7f4fbeda 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java @@ -972,11 +972,11 @@ public DemisSteps( if (webDriverHelpers.isElementVisibleWithTimeout(CASE_SAVED_POPUP_DE, 5)) { webDriverHelpers.clickOnWebElementBySelector(CASE_SAVED_POPUP_DE); } - webDriverHelpers.waitUntilIdentifiedElementIsPresent(NEXT_BUTTON); + webDriverHelpers.scrollToElement(NEXT_BUTTON); webDriverHelpers.clickOnWebElementBySelector(NEXT_BUTTON); webDriverHelpers.waitUntilIdentifiedElementIsPresent(CASE_SAVED_POPUP_DE); webDriverHelpers.clickOnWebElementBySelector(CASE_SAVED_POPUP_DE); - TimeUnit.SECONDS.sleep(2); + TimeUnit.SECONDS.sleep(5); }); } From bec8bdfea407b77b486ef8614f683c7a970ec090 Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Tue, 1 Aug 2023 13:56:57 +0200 Subject: [PATCH 141/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. Changes in clicking next button method --- .../org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java | 1 + 1 file changed, 1 insertion(+) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java index 7ed7f4fbeda..d2dc75f20a4 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java @@ -949,6 +949,7 @@ public DemisSteps( case "save and open case": webDriverHelpers.waitUntilElementIsVisibleAndClickable(POPUP_WINDOW_SAVE_AND_OPEN_PHYSICIAN_REPORT_BUTTON); webDriverHelpers.clickOnWebElementBySelector(POPUP_WINDOW_SAVE_AND_OPEN_PHYSICIAN_REPORT_BUTTON); + webDriverHelpers.waitForPageLoadingSpinnerToDisappear(15); break; case "cancel": webDriverHelpers.waitUntilElementIsVisibleAndClickable(POPUP_WINDOW_CANCEL_BUTTON); From e6b48e28bbc5998a4d670cf64aa0cfbd764e048f Mon Sep 17 00:00:00 2001 From: Razvan Date: Tue, 1 Aug 2023 15:28:28 +0300 Subject: [PATCH 142/174] SORQA-1050 : correction --- .../resources/features/sanity/web/SharedContacts.feature | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedContacts.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedContacts.feature index b9188e380f9..bd1fbbcd650 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedContacts.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/SharedContacts.feature @@ -333,12 +333,12 @@ Feature: Sharing contacts between environments tests And I click on the Contacts button from navbar Then I open the last created contact via API And I check if editable fields are read only for shared contact - And I check if handover card contains "Eigentümer: LK Fulda" information + And I check if handover card contains shared with "s2s_2" information And I check if handover card contains "Geteilt von: S2S USER" information And I check if handover card contains "shared with automated test" information Then I navigate to "s2s_2" environment Then I open the last created contact via API - And I check if handover card contains "Gesendet von LK Barnim" information + And I check if handover card contains shared with "s2s_1" information And I check if handover card contains "Geteilt von: S2S User" information And I check if handover card contains "shared with automated test" information @@ -371,7 +371,7 @@ Feature: Sharing contacts between environments tests And I select organization to share with "s2s_2" And I fill comment in share popup for contact with random string Then I click on share button in s2s share popup and wait for share to finish - And I check if handover card contains "LK Fulda" information + And I check if handover card contains shared with "s2s_2" information And I check if handover card contains "Geteilt von: S2S USER" information Then I back to tab number 2 And I refresh current page From 65d8f09015bd60e99d166be758660838d5cf9c6a Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Tue, 1 Aug 2023 14:39:34 +0200 Subject: [PATCH 143/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. New next method while prcessing lab message. --- .../messages/MessagesDirectoryPage.java | 4 +++ .../steps/api/demisSteps/DemisSteps.java | 1 - .../messages/MessagesDirectorySteps.java | 27 +++++++++++++++++++ .../features/sanity/web/DemisWeb.feature | 6 ++--- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java index 15a6daa73e5..df7ca58e91b 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java @@ -154,4 +154,8 @@ public static By getProcessStatusByIndex(int index) { public static final By CASE_SAVED_POPUP_DE = By.cssSelector(".warning .v-Notification-caption"); public static final By TYPE_OF_MESSAGE_COMBOBOX = By.cssSelector("[id='type'] [class='v-filterselect-button']"); public static final By GRID_RESULTS_TYPE = By.cssSelector("tr:nth-of-type(1) > td:nth-of-type(3)"); + public static final By CURRENT_HOSPITALIZATION_HEADER = By.cssSelector("[location='hospitalizationHeadingLoc'] div"); + public static final By CLINICAL_MEASUREMENT_HEADER = By.cssSelector("[location='clinicalMeasurementsHeadingLoc'] div"); + public static final By EXPOSURE_INVESTIGATION_HEADER = By.cssSelector("[location='locExposureInvestigationHeading'] div"); + public static final By ADD_VACCINATION_BUTTON = By.id("physiciansReportCaseAddVaccination"); } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java index d2dc75f20a4..1e71842107f 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java @@ -977,7 +977,6 @@ public DemisSteps( webDriverHelpers.clickOnWebElementBySelector(NEXT_BUTTON); webDriverHelpers.waitUntilIdentifiedElementIsPresent(CASE_SAVED_POPUP_DE); webDriverHelpers.clickOnWebElementBySelector(CASE_SAVED_POPUP_DE); - TimeUnit.SECONDS.sleep(5); }); } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java index 154e4c844ab..ae2b5396a43 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java @@ -367,5 +367,32 @@ public MessagesDirectorySteps( softly.assertAll(); }); + + And( + "I click next button while processing a {string} in DEMIS LabMessage", + (String option) -> { + if (webDriverHelpers.isElementVisibleWithTimeout(CASE_SAVED_POPUP_DE, 5)) { + webDriverHelpers.clickOnWebElementBySelector(CASE_SAVED_POPUP_DE); + } + switch(option) { + case "hospitalization": + webDriverHelpers.waitUntilIdentifiedElementIsPresent(CURRENT_HOSPITALIZATION_HEADER); + webDriverHelpers.scrollToElement(NEXT_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(NEXT_BUTTON); + break; + case "clinical measurement": + webDriverHelpers.waitUntilIdentifiedElementIsPresent(CLINICAL_MEASUREMENT_HEADER); + webDriverHelpers.scrollToElement(NEXT_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(NEXT_BUTTON); + break; + case "exposure investigation": + webDriverHelpers.waitUntilIdentifiedElementIsPresent(EXPOSURE_INVESTIGATION_HEADER); + webDriverHelpers.scrollToElement(NEXT_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(NEXT_BUTTON); + webDriverHelpers.waitUntilIdentifiedElementIsPresent(ADD_VACCINATION_BUTTON); + break; + } + + }); } } diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index b448f2e1565..16f80223988 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -617,9 +617,9 @@ Scenario: Create and send laboratory request via Demis And I pick a new person in Pick or create person popup during case creation for DE And I fill only mandatory fields to convert laboratory message into a case for DE And I click on "save" button in new physician report form while processing a message - And I click next button while processing a DEMIS LabMessage - And I click next button while processing a DEMIS LabMessage - And I click next button while processing a DEMIS LabMessage + And I click next button while processing a "hospitalization" in DEMIS LabMessage + And I click next button while processing a "clinical measurement" in DEMIS LabMessage + And I click next button while processing a "exposure investigation" in DEMIS LabMessage And I click on "save and open" button in new physician report form while processing a message Then I check if there is no displayed sample result on Edit case page And I click on Display associated external messages button from Reports side component From b7f593d5b213bf93f626df9eddbd26628fd31d93 Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Tue, 1 Aug 2023 14:55:25 +0200 Subject: [PATCH 144/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. New next method while prcessing lab message. --- .../src/test/resources/features/sanity/web/DemisWeb.feature | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index 16f80223988..3104eb362e6 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -620,7 +620,11 @@ Scenario: Create and send laboratory request via Demis And I click next button while processing a "hospitalization" in DEMIS LabMessage And I click next button while processing a "clinical measurement" in DEMIS LabMessage And I click next button while processing a "exposure investigation" in DEMIS LabMessage - And I click on "save and open" button in new physician report form while processing a message + And I click on "save" button in new physician report form while processing a message +# And I click on "save and open" button in new physician report form while processing a message + And I click on the Cases button from navbar + And I search the case by last created person via Demis message + Then I click on the first Case ID from Case Directory Then I check if there is no displayed sample result on Edit case page And I click on Display associated external messages button from Reports side component And I check if external message window appears and close it From 6f0f38a708503c687ce11ee50cedbcb8b9b8274d Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Tue, 1 Aug 2023 15:06:40 +0200 Subject: [PATCH 145/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. New next method while prcessing lab message. --- .../web/application/messages/MessagesDirectorySteps.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java index ae2b5396a43..3878aa75b5a 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java @@ -18,7 +18,7 @@ import java.util.concurrent.TimeUnit; import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.ACTION_CONFIRM_POPUP_BUTTON; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.SAMPLES_CARD_DATE_OF_COLLECTED_SAMPLE; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.SAMPLES_CARD_LABORATORY; import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.*; @Slf4j @@ -362,7 +362,7 @@ public MessagesDirectorySteps( "^I check if there is no displayed sample result on Edit case page$", () -> { softly.assertFalse( - webDriverHelpers.isElementPresent(SAMPLES_CARD_DATE_OF_COLLECTED_SAMPLE), + webDriverHelpers.isElementPresent(SAMPLES_CARD_LABORATORY), "Element is present!"); softly.assertAll(); From 404bfaaac6da5c91035743cdd2af5fa51a78f6a1 Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Tue, 1 Aug 2023 15:23:13 +0200 Subject: [PATCH 146/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. New next method while prcessing lab message. --- .../src/test/resources/features/sanity/web/DemisWeb.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index 3104eb362e6..10dbaf05573 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -631,6 +631,6 @@ Scenario: Create and send laboratory request via Demis Then I click on the Messages button from navbar And I filter by last created person via API in Messages Directory And I verify that status for result 1 is set to processed in Message Directory page - And I select "Physician's report" type of message in Message Directory page + And I select "Arztmeldung" type of message in Message Directory page And I click on the APPLY FILTERS button - And I check that all displayed messages have "Physician's report" in grid Message Directory Type column \ No newline at end of file + And I check that all displayed messages have "Arztmeldung" in grid Message Directory Type column \ No newline at end of file From 6aa013aeb490064e306c98b513f0915a1c29dd61 Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Wed, 2 Aug 2023 07:52:06 +0200 Subject: [PATCH 147/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. New steps have been added. --- .../messages/MessagesDirectoryPage.java | 1 + .../messages/MessagesDirectorySteps.java | 18 ++++++++++++++++++ .../features/sanity/web/DemisWeb.feature | 12 +++++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java index df7ca58e91b..5c6dc7f8129 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java @@ -158,4 +158,5 @@ public static By getProcessStatusByIndex(int index) { public static final By CLINICAL_MEASUREMENT_HEADER = By.cssSelector("[location='clinicalMeasurementsHeadingLoc'] div"); public static final By EXPOSURE_INVESTIGATION_HEADER = By.cssSelector("[location='locExposureInvestigationHeading'] div"); public static final By ADD_VACCINATION_BUTTON = By.id("physiciansReportCaseAddVaccination"); + public static final By DOWNLOAD_BUTTON = By.cssSelector(".component-wrap [role='button'] .v-icon"); } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java index 3878aa75b5a..65b2a64d92f 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java @@ -6,11 +6,13 @@ import org.openqa.selenium.interactions.Actions; import org.sormas.e2etests.helpers.AssertHelpers; import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.helpers.files.FilesHelper; import org.sormas.e2etests.steps.BaseSteps; import org.testng.Assert; import org.testng.asserts.SoftAssert; import javax.inject.Inject; +import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -392,7 +394,23 @@ public MessagesDirectorySteps( webDriverHelpers.waitUntilIdentifiedElementIsPresent(ADD_VACCINATION_BUTTON); break; } + }); + And( + "^I download message from Message Directory page$", + () -> { + webDriverHelpers.clickOnWebElementBySelector(DOWNLOAD_BUTTON); + TimeUnit.SECONDS.sleep(5); // wait for download + }); + + And( + "I verify if lab message file is downloaded correctly", + () -> { + String shortenedUUID = uuids.get(0); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); + String file = "sormas_lab_message_" + shortenedUUID + "_" + formatter.format(LocalDate.now()) + ".pdf"; + FilesHelper.waitForFileToDownload(file, 40); + FilesHelper.deleteFile(file); }); } } diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index 10dbaf05573..7a7d73964ac 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -613,6 +613,7 @@ Scenario: Create and send laboratory request via Demis And I click on the Messages button from navbar And I click on fetch messages button And I filter by last created person via API in Messages Directory + And I collect message uuid And I click on Verarbeiten button in Messages Directory And I pick a new person in Pick or create person popup during case creation for DE And I fill only mandatory fields to convert laboratory message into a case for DE @@ -633,4 +634,13 @@ Scenario: Create and send laboratory request via Demis And I verify that status for result 1 is set to processed in Message Directory page And I select "Arztmeldung" type of message in Message Directory page And I click on the APPLY FILTERS button - And I check that all displayed messages have "Arztmeldung" in grid Message Directory Type column \ No newline at end of file + And I check that all displayed messages have "Arztmeldung" in grid Message Directory Type column + When I create and send Laboratory Notification for physician report + And I click on the Messages button from navbar + And I click on fetch messages button + And I filter by last created person via API in Messages Directory + And I select "Arztmeldung" type of message in Message Directory page + And I download message from Message Directory page + And I download created custom case export file + And I download last updated document file from case tab + And I verify if lab message file is downloaded correctly \ No newline at end of file From 74e80b34a1de20ae6b21a0fa5bb0b6ec3fef6276 Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Wed, 2 Aug 2023 08:11:48 +0200 Subject: [PATCH 148/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. New steps have been added. --- .../application/messages/MessagesDirectoryPage.java | 1 + .../web/application/messages/MessagesDirectorySteps.java | 9 ++++++++- .../test/resources/features/sanity/web/DemisWeb.feature | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java index 5c6dc7f8129..32060a30510 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java @@ -159,4 +159,5 @@ public static By getProcessStatusByIndex(int index) { public static final By EXPOSURE_INVESTIGATION_HEADER = By.cssSelector("[location='locExposureInvestigationHeading'] div"); public static final By ADD_VACCINATION_BUTTON = By.id("physiciansReportCaseAddVaccination"); public static final By DOWNLOAD_BUTTON = By.cssSelector(".component-wrap [role='button'] .v-icon"); + public static final By GRID_MESSAGE_UUID_TITLE = By.cssSelector("tr:nth-of-type(1) > td:nth-of-type(2) a"); } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java index 65b2a64d92f..e1323d968df 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java @@ -27,6 +27,7 @@ public class MessagesDirectorySteps implements En { public static List uuids = new ArrayList<>(); + public static List shortenedUUIDS = new ArrayList<>(); @Inject public MessagesDirectorySteps( @@ -406,11 +407,17 @@ public MessagesDirectorySteps( And( "I verify if lab message file is downloaded correctly", () -> { - String shortenedUUID = uuids.get(0); + String shortenedUUID = shortenedUUIDS.get(0); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); String file = "sormas_lab_message_" + shortenedUUID + "_" + formatter.format(LocalDate.now()) + ".pdf"; FilesHelper.waitForFileToDownload(file, 40); FilesHelper.deleteFile(file); }); + + And( + "^I collect shortened message uuid from Message Directory page$", + () -> { + shortenedUUIDS.add(webDriverHelpers.getValueFromWebElement(GRID_MESSAGE_UUID_TITLE)); + }); } } diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index 7a7d73964ac..8a3f261139f 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -613,7 +613,7 @@ Scenario: Create and send laboratory request via Demis And I click on the Messages button from navbar And I click on fetch messages button And I filter by last created person via API in Messages Directory - And I collect message uuid + And I collect shortened message uuid from Message Directory page And I click on Verarbeiten button in Messages Directory And I pick a new person in Pick or create person popup during case creation for DE And I fill only mandatory fields to convert laboratory message into a case for DE From a60ff1fc1e0c927d51d293365d574484beb68d12 Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Wed, 2 Aug 2023 08:35:29 +0200 Subject: [PATCH 149/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. Get value has been changed to get text. --- .../steps/web/application/messages/MessagesDirectorySteps.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java index e1323d968df..f538f5a6ac8 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java @@ -417,7 +417,7 @@ public MessagesDirectorySteps( And( "^I collect shortened message uuid from Message Directory page$", () -> { - shortenedUUIDS.add(webDriverHelpers.getValueFromWebElement(GRID_MESSAGE_UUID_TITLE)); + shortenedUUIDS.add(webDriverHelpers.getTextFromWebElement(GRID_MESSAGE_UUID_TITLE)); }); } } From 4beff03d76a6eeb0099e0465e1c7c9750a2a45ed Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Wed, 2 Aug 2023 09:11:53 +0200 Subject: [PATCH 150/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. download button locator has been changed --- .../application/messages/MessagesDirectoryPage.java | 2 +- .../resources/features/sanity/web/DemisWeb.feature | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java index 32060a30510..a6d0b0ad23b 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java @@ -158,6 +158,6 @@ public static By getProcessStatusByIndex(int index) { public static final By CLINICAL_MEASUREMENT_HEADER = By.cssSelector("[location='clinicalMeasurementsHeadingLoc'] div"); public static final By EXPOSURE_INVESTIGATION_HEADER = By.cssSelector("[location='locExposureInvestigationHeading'] div"); public static final By ADD_VACCINATION_BUTTON = By.id("physiciansReportCaseAddVaccination"); - public static final By DOWNLOAD_BUTTON = By.cssSelector(".component-wrap [role='button'] .v-icon"); + public static final By DOWNLOAD_BUTTON = By.cssSelector("tr:nth-of-type(1) > td:nth-of-type(15) div"); public static final By GRID_MESSAGE_UUID_TITLE = By.cssSelector("tr:nth-of-type(1) > td:nth-of-type(2) a"); } diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index 8a3f261139f..32fedfdbb43 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -635,12 +635,10 @@ Scenario: Create and send laboratory request via Demis And I select "Arztmeldung" type of message in Message Directory page And I click on the APPLY FILTERS button And I check that all displayed messages have "Arztmeldung" in grid Message Directory Type column - When I create and send Laboratory Notification for physician report - And I click on the Messages button from navbar - And I click on fetch messages button - And I filter by last created person via API in Messages Directory - And I select "Arztmeldung" type of message in Message Directory page +# When I create and send Laboratory Notification for physician report +# And I click on the Messages button from navbar +# And I click on fetch messages button +# And I filter by last created person via API in Messages Directory +# And I select "Arztmeldung" type of message in Message Directory page And I download message from Message Directory page - And I download created custom case export file - And I download last updated document file from case tab And I verify if lab message file is downloaded correctly \ No newline at end of file From ba9e4993efe8cd81d0911a4dfe928b80f874bd51 Mon Sep 17 00:00:00 2001 From: Martin Wahnschaffe Date: Wed, 2 Aug 2023 09:39:07 +0200 Subject: [PATCH 151/174] Disable dependency check oss index to workarround rate limit issue https://github.com/jeremylong/DependencyCheck/issues/4539#issuecomment-1137183801 --- sormas-base/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index 78eb2135ef3..745eea5cfc7 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -1708,6 +1708,7 @@ ${dependency-check.suppressionFile} false + false From 3a1dac110218d7116888e0514108630cc0a41b03 Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Wed, 2 Aug 2023 10:15:11 +0200 Subject: [PATCH 152/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. Date formatter has been changed. --- .../steps/web/application/messages/MessagesDirectorySteps.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java index f538f5a6ac8..b9f48386e3a 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java @@ -408,7 +408,7 @@ public MessagesDirectorySteps( "I verify if lab message file is downloaded correctly", () -> { String shortenedUUID = shortenedUUIDS.get(0); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd"); String file = "sormas_lab_message_" + shortenedUUID + "_" + formatter.format(LocalDate.now()) + ".pdf"; FilesHelper.waitForFileToDownload(file, 40); FilesHelper.deleteFile(file); From 999fbd908638a70dfe6d85a84b41a611587005df Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Wed, 2 Aug 2023 10:45:14 +0200 Subject: [PATCH 153/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. Date formatter has been changed. --- .../steps/web/application/messages/MessagesDirectorySteps.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java index b9f48386e3a..9cfae659c45 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java @@ -408,7 +408,7 @@ public MessagesDirectorySteps( "I verify if lab message file is downloaded correctly", () -> { String shortenedUUID = shortenedUUIDS.get(0); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd"); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); String file = "sormas_lab_message_" + shortenedUUID + "_" + formatter.format(LocalDate.now()) + ".pdf"; FilesHelper.waitForFileToDownload(file, 40); FilesHelper.deleteFile(file); From 6e1905ff5bf90e2d7d6e6ffb88860d086da78436 Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Wed, 2 Aug 2023 12:07:11 +0200 Subject: [PATCH 154/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. New steps added. --- .../pages/application/messages/MessagesDirectoryPage.java | 4 +++- .../web/application/messages/MessagesDirectorySteps.java | 4 ++-- .../src/test/resources/features/sanity/web/DemisWeb.feature | 6 ------ 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java index a6d0b0ad23b..b8ea24959b2 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java @@ -158,6 +158,8 @@ public static By getProcessStatusByIndex(int index) { public static final By CLINICAL_MEASUREMENT_HEADER = By.cssSelector("[location='clinicalMeasurementsHeadingLoc'] div"); public static final By EXPOSURE_INVESTIGATION_HEADER = By.cssSelector("[location='locExposureInvestigationHeading'] div"); public static final By ADD_VACCINATION_BUTTON = By.id("physiciansReportCaseAddVaccination"); - public static final By DOWNLOAD_BUTTON = By.cssSelector("tr:nth-of-type(1) > td:nth-of-type(15) div"); + // public static final By DOWNLOAD_BUTTON = + // By.cssSelector("tr:nth-of-type(1) > td:nth-of-type(15) div div"); + public static final By DOWNLOAD_BUTTON = By.xpath("//table/tbody/tr[1]/td[14]/div"); public static final By GRID_MESSAGE_UUID_TITLE = By.cssSelector("tr:nth-of-type(1) > td:nth-of-type(2) a"); } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java index 9cfae659c45..807bcfbef37 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java @@ -368,7 +368,6 @@ public MessagesDirectorySteps( webDriverHelpers.isElementPresent(SAMPLES_CARD_LABORATORY), "Element is present!"); softly.assertAll(); - }); And( @@ -377,7 +376,7 @@ public MessagesDirectorySteps( if (webDriverHelpers.isElementVisibleWithTimeout(CASE_SAVED_POPUP_DE, 5)) { webDriverHelpers.clickOnWebElementBySelector(CASE_SAVED_POPUP_DE); } - switch(option) { + switch (option) { case "hospitalization": webDriverHelpers.waitUntilIdentifiedElementIsPresent(CURRENT_HOSPITALIZATION_HEADER); webDriverHelpers.scrollToElement(NEXT_BUTTON); @@ -400,6 +399,7 @@ public MessagesDirectorySteps( And( "^I download message from Message Directory page$", () -> { + webDriverHelpers.scrollToElement(DOWNLOAD_BUTTON); webDriverHelpers.clickOnWebElementBySelector(DOWNLOAD_BUTTON); TimeUnit.SECONDS.sleep(5); // wait for download }); diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index 32fedfdbb43..863213ef0e6 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -622,7 +622,6 @@ Scenario: Create and send laboratory request via Demis And I click next button while processing a "clinical measurement" in DEMIS LabMessage And I click next button while processing a "exposure investigation" in DEMIS LabMessage And I click on "save" button in new physician report form while processing a message -# And I click on "save and open" button in new physician report form while processing a message And I click on the Cases button from navbar And I search the case by last created person via Demis message Then I click on the first Case ID from Case Directory @@ -635,10 +634,5 @@ Scenario: Create and send laboratory request via Demis And I select "Arztmeldung" type of message in Message Directory page And I click on the APPLY FILTERS button And I check that all displayed messages have "Arztmeldung" in grid Message Directory Type column -# When I create and send Laboratory Notification for physician report -# And I click on the Messages button from navbar -# And I click on fetch messages button -# And I filter by last created person via API in Messages Directory -# And I select "Arztmeldung" type of message in Message Directory page And I download message from Message Directory page And I verify if lab message file is downloaded correctly \ No newline at end of file From 62afc114eba4d25083659d7c0af69222343611b7 Mon Sep 17 00:00:00 2001 From: Levente Gal Date: Wed, 2 Aug 2023 13:17:51 +0300 Subject: [PATCH 155/174] #12028 Add the disease variant to the edit forms of cases in Bulk action - add placeholder for empty selection so user are awere that it will delete the varinat from cases --- .../java/de/symeda/sormas/ui/caze/BulkCaseDataForm.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/BulkCaseDataForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/BulkCaseDataForm.java index c8fc07d5644..7076b57c907 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/BulkCaseDataForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/BulkCaseDataForm.java @@ -66,6 +66,7 @@ import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.ui.utils.AbstractEditForm; import de.symeda.sormas.ui.utils.ComboBoxHelper; +import de.symeda.sormas.ui.utils.ComboBoxWithPlaceholder; import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.NullableOptionGroup; @@ -211,12 +212,14 @@ protected void addFields() { diseaseVariantCheckBox.setVisible(false); getContent().addComponent(diseaseVariantCheckBox, DISEASE_VARIANT_CHECKBOX); - ComboBox diseaseVariantField = addField(CaseBulkEditData.DISEASE_VARIANT, ComboBox.class); + ComboBoxWithPlaceholder diseaseVariantField = addField(CaseBulkEditData.DISEASE_VARIANT, ComboBoxWithPlaceholder.class); + diseaseVariantField.setPlaceholder(I18nProperties.getCaption(Captions.caseNoDiseaseVariant)); + diseaseVariantField.setNullSelectionAllowed(true); diseaseVariantField.setEnabled(false); + diseaseVariantField.setVisible(false); + TextField diseaseVariantDetailsField = addField(CaseBulkEditData.DISEASE_VARIANT_DETAILS, TextField.class); diseaseVariantDetailsField.setVisible(false); - diseaseVariantField.setNullSelectionAllowed(true); - diseaseVariantField.setVisible(false); diseaseVariantField.addValueChangeListener(e -> { DiseaseVariant diseaseVariant = (DiseaseVariant) e.getProperty().getValue(); From ca7bdcaa3f41987423feb2cc5a04f37f9dc5e5ca Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Wed, 2 Aug 2023 13:12:28 +0200 Subject: [PATCH 156/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. New steps added. --- .../messages/MessagesDirectoryPage.java | 2 +- .../features/sanity/web/DemisWeb.feature | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java index b8ea24959b2..0b7887d5871 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java @@ -160,6 +160,6 @@ public static By getProcessStatusByIndex(int index) { public static final By ADD_VACCINATION_BUTTON = By.id("physiciansReportCaseAddVaccination"); // public static final By DOWNLOAD_BUTTON = // By.cssSelector("tr:nth-of-type(1) > td:nth-of-type(15) div div"); - public static final By DOWNLOAD_BUTTON = By.xpath("//table/tbody/tr[1]/td[14]/div"); + public static final By DOWNLOAD_BUTTON = By.xpath("//table/tbody/tr[1]/td[15]/div"); public static final By GRID_MESSAGE_UUID_TITLE = By.cssSelector("tr:nth-of-type(1) > td:nth-of-type(2) a"); } diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index 863213ef0e6..d7aecf315b0 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -633,6 +633,23 @@ Scenario: Create and send laboratory request via Demis And I verify that status for result 1 is set to processed in Message Directory page And I select "Arztmeldung" type of message in Message Directory page And I click on the APPLY FILTERS button + And I click on "Verarbeitet" quick filter above the messages in Message directory page + And I check that all displayed messages have "Arztmeldung" in grid Message Directory Type column + And I download message from Message Directory page + And I verify if lab message file is downloaded correctly + + @tmsLink=SORQA-1024Test @env_d2s @LoginKeycloak + Scenario: Demis - Process a Physician Report[2] + Given API : Login to DEMIS server + When I create and send Laboratory Notification for physician report + And I log in as a Admin User + And I click on the Messages button from navbar + And I click on fetch messages button + And I filter by last created person via API in Messages Directory + And I collect shortened message uuid from Message Directory page + And I select "Arztmeldung" type of message in Message Directory page + And I click on the APPLY FILTERS button + And I click on "Unverarbeitet" quick filter above the messages in Message directory page And I check that all displayed messages have "Arztmeldung" in grid Message Directory Type column And I download message from Message Directory page And I verify if lab message file is downloaded correctly \ No newline at end of file From b242dca82aca38f32aaae87d7e2e149f11bfedbf Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Thu, 3 Aug 2023 08:28:26 +0200 Subject: [PATCH 157/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. New steps added. --- .../messages/MessagesDirectoryPage.java | 29 +++-- .../messages/MessagesDirectorySteps.java | 111 ++++++++++++++---- .../features/sanity/web/DemisWeb.feature | 12 +- 3 files changed, 117 insertions(+), 35 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java index 0b7887d5871..5226358e5ac 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java @@ -148,18 +148,29 @@ public static By getProcessStatusByIndex(int index) { public static final By NEW_SAMPLE_FORM_SECOND_PATHOGEN_TEST_TYPE_INPUT = By.xpath("(//div[contains(@id, 'testType')]//input)[2]"); public static final By POPUP_WINDOW_SAVE_AND_OPEN_PHYSICIAN_REPORT_BUTTON = - By.id("actionSaveAndOpenCase"); + By.id("actionSaveAndOpenCase"); public static final By POPUP_WINDOW_BACK_BUTTON = By.id("actionBack"); public static final By NEXT_BUTTON = By.id("actionNext"); public static final By CASE_SAVED_POPUP_DE = By.cssSelector(".warning .v-Notification-caption"); - public static final By TYPE_OF_MESSAGE_COMBOBOX = By.cssSelector("[id='type'] [class='v-filterselect-button']"); - public static final By GRID_RESULTS_TYPE = By.cssSelector("tr:nth-of-type(1) > td:nth-of-type(3)"); - public static final By CURRENT_HOSPITALIZATION_HEADER = By.cssSelector("[location='hospitalizationHeadingLoc'] div"); - public static final By CLINICAL_MEASUREMENT_HEADER = By.cssSelector("[location='clinicalMeasurementsHeadingLoc'] div"); - public static final By EXPOSURE_INVESTIGATION_HEADER = By.cssSelector("[location='locExposureInvestigationHeading'] div"); + public static final By TYPE_OF_MESSAGE_COMBOBOX = + By.cssSelector("[id='type'] [class='v-filterselect-button']"); + public static final By GRID_RESULTS_TYPE = + By.cssSelector("tr:nth-of-type(1) > td:nth-of-type(3)"); + public static final By CURRENT_HOSPITALIZATION_HEADER = + By.cssSelector("[location='hospitalizationHeadingLoc'] div"); + public static final By CLINICAL_MEASUREMENT_HEADER = + By.cssSelector("[location='clinicalMeasurementsHeadingLoc'] div"); + public static final By EXPOSURE_INVESTIGATION_HEADER = + By.cssSelector("[location='locExposureInvestigationHeading'] div"); public static final By ADD_VACCINATION_BUTTON = By.id("physiciansReportCaseAddVaccination"); - // public static final By DOWNLOAD_BUTTON = - // By.cssSelector("tr:nth-of-type(1) > td:nth-of-type(15) div div"); public static final By DOWNLOAD_BUTTON = By.xpath("//table/tbody/tr[1]/td[15]/div"); - public static final By GRID_MESSAGE_UUID_TITLE = By.cssSelector("tr:nth-of-type(1) > td:nth-of-type(2) a"); + public static final By GRID_MESSAGE_UUID_TITLE = + By.cssSelector("tr:nth-of-type(1) > td:nth-of-type(2) a"); + public static final By ASSIGN_BUTTON = By.xpath("//table/tbody/tr[1]/td[14]/div"); + public static final By ASSIGNEE_LABEL = By.cssSelector(".component-wrap .v-label"); + public static final By EDIT_ASSIGNEE_FILTER_SELECT_BUTTON = + By.cssSelector(".popupContent .v-filterselect-button"); + public static final By SEND_TO_ANOTHER_ORGANIZATION_BUTTON = + By.id("sormasToSormasSendLabMessage"); + public static final By HEADER_OF_ENTRY_LINK = By.cssSelector(".HeaderOfEntry"); } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java index 807bcfbef37..4929e17623c 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java @@ -365,8 +365,7 @@ public MessagesDirectorySteps( "^I check if there is no displayed sample result on Edit case page$", () -> { softly.assertFalse( - webDriverHelpers.isElementPresent(SAMPLES_CARD_LABORATORY), - "Element is present!"); + webDriverHelpers.isElementPresent(SAMPLES_CARD_LABORATORY), "Element is present!"); softly.assertAll(); }); @@ -374,25 +373,25 @@ public MessagesDirectorySteps( "I click next button while processing a {string} in DEMIS LabMessage", (String option) -> { if (webDriverHelpers.isElementVisibleWithTimeout(CASE_SAVED_POPUP_DE, 5)) { - webDriverHelpers.clickOnWebElementBySelector(CASE_SAVED_POPUP_DE); + webDriverHelpers.clickOnWebElementBySelector(CASE_SAVED_POPUP_DE); } switch (option) { - case "hospitalization": - webDriverHelpers.waitUntilIdentifiedElementIsPresent(CURRENT_HOSPITALIZATION_HEADER); - webDriverHelpers.scrollToElement(NEXT_BUTTON); - webDriverHelpers.clickOnWebElementBySelector(NEXT_BUTTON); - break; - case "clinical measurement": - webDriverHelpers.waitUntilIdentifiedElementIsPresent(CLINICAL_MEASUREMENT_HEADER); - webDriverHelpers.scrollToElement(NEXT_BUTTON); - webDriverHelpers.clickOnWebElementBySelector(NEXT_BUTTON); - break; - case "exposure investigation": - webDriverHelpers.waitUntilIdentifiedElementIsPresent(EXPOSURE_INVESTIGATION_HEADER); - webDriverHelpers.scrollToElement(NEXT_BUTTON); - webDriverHelpers.clickOnWebElementBySelector(NEXT_BUTTON); - webDriverHelpers.waitUntilIdentifiedElementIsPresent(ADD_VACCINATION_BUTTON); - break; + case "hospitalization": + webDriverHelpers.waitUntilIdentifiedElementIsPresent(CURRENT_HOSPITALIZATION_HEADER); + webDriverHelpers.scrollToElement(NEXT_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(NEXT_BUTTON); + break; + case "clinical measurement": + webDriverHelpers.waitUntilIdentifiedElementIsPresent(CLINICAL_MEASUREMENT_HEADER); + webDriverHelpers.scrollToElement(NEXT_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(NEXT_BUTTON); + break; + case "exposure investigation": + webDriverHelpers.waitUntilIdentifiedElementIsPresent(EXPOSURE_INVESTIGATION_HEADER); + webDriverHelpers.scrollToElement(NEXT_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(NEXT_BUTTON); + webDriverHelpers.waitUntilIdentifiedElementIsPresent(ADD_VACCINATION_BUTTON); + break; } }); @@ -409,15 +408,79 @@ public MessagesDirectorySteps( () -> { String shortenedUUID = shortenedUUIDS.get(0); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); - String file = "sormas_lab_message_" + shortenedUUID + "_" + formatter.format(LocalDate.now()) + ".pdf"; + String file = + "sormas_lab_message_" + + shortenedUUID + + "_" + + formatter.format(LocalDate.now()) + + ".pdf"; FilesHelper.waitForFileToDownload(file, 40); FilesHelper.deleteFile(file); }); And( - "^I collect shortened message uuid from Message Directory page$", - () -> { - shortenedUUIDS.add(webDriverHelpers.getTextFromWebElement(GRID_MESSAGE_UUID_TITLE)); - }); + "^I collect shortened message uuid from Message Directory page$", + () -> { + shortenedUUIDS.add(webDriverHelpers.getTextFromWebElement(GRID_MESSAGE_UUID_TITLE)); + }); + + And( + "I assign the Assignee to the message on Message Directory page", + () -> { + webDriverHelpers.clickOnWebElementBySelector(ASSIGN_BUTTON); + webDriverHelpers.selectFromCombobox(EDIT_ASSIGNEE_FILTER_SELECT_BUTTON, "Ad MIN"); + TimeUnit.SECONDS.sleep(5); + webDriverHelpers.clickOnWebElementBySelector(POPUP_WINDOW_SAVE_BUTTON); + }); + + And( + "^I check that \"([^\"]*)\" is assigned to the message on Message Directory page$", + (String assignee) -> { + webDriverHelpers.refreshCurrentPage(); + softly.assertEquals( + webDriverHelpers.getTextFromPresentWebElement(ASSIGNEE_LABEL), + assignee, + "Incorrect value is assigned to the assignee"); + softly.assertAll(); + }); + + Then( + "^I check if there are all needed buttons in HTML message file$", + () -> { + webDriverHelpers.scrollToElement(MESSAGE_DELETE_BUTTON); + webDriverHelpers.waitUntilIdentifiedElementIsPresent(MESSAGE_DELETE_BUTTON); + webDriverHelpers.waitUntilIdentifiedElementIsPresent(MARK_AS_UNCLEAR_BUTTON); + webDriverHelpers.waitUntilIdentifiedElementIsPresent(MARK_AS_FORWARDED_BUTTON); + webDriverHelpers.waitUntilIdentifiedElementIsPresent(SEND_TO_ANOTHER_ORGANIZATION_BUTTON); + }); + + And( + "^I close HTML message$", + () -> { + webDriverHelpers.clickOnWebElementBySelector(CLOSE_POPUP); + webDriverHelpers.waitForPageLoaded(); + }); + + Then( + "^I check if there are any buttons in HTML message file$", + () -> { + webDriverHelpers.scrollToElement(HEADER_OF_ENTRY_LINK); + softly.assertTrue( + webDriverHelpers.isElementPresent(MESSAGE_DELETE_BUTTON), + "Delete message is available!"); + softly.assertAll(); + softly.assertTrue( + webDriverHelpers.isElementPresent(MARK_AS_UNCLEAR_BUTTON), + "Delete message is available!"); + softly.assertAll(); + softly.assertTrue( + webDriverHelpers.isElementPresent(MARK_AS_FORWARDED_BUTTON), + "Delete message is available!"); + softly.assertAll(); + softly.assertTrue( + webDriverHelpers.isElementPresent(SEND_TO_ANOTHER_ORGANIZATION_BUTTON), + "Delete message is available!"); + softly.assertAll(); + }); } } diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index d7aecf315b0..0118d903ed1 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -606,7 +606,7 @@ Scenario: Create and send laboratory request via Demis And I verify that status for result 1 is set to processed in Message Directory page @tmsLink=SORQA-1024 @env_d2s @LoginKeycloak - Scenario: Demis - Process a Physician Report + Scenario: Demis - Process a Physician Report[1] Given API : Login to DEMIS server When I create and send Laboratory Notification for physician report And I log in as a Admin User @@ -635,10 +635,13 @@ Scenario: Create and send laboratory request via Demis And I click on the APPLY FILTERS button And I click on "Verarbeitet" quick filter above the messages in Message directory page And I check that all displayed messages have "Arztmeldung" in grid Message Directory Type column + And I click on the eye icon next for the first fetched message + Then I check if there are any buttons in HTML message file + And I close HTML message And I download message from Message Directory page And I verify if lab message file is downloaded correctly - @tmsLink=SORQA-1024Test @env_d2s @LoginKeycloak + @tmsLink=SORQA-1024 @env_d2s @LoginKeycloak Scenario: Demis - Process a Physician Report[2] Given API : Login to DEMIS server When I create and send Laboratory Notification for physician report @@ -651,5 +654,10 @@ Scenario: Create and send laboratory request via Demis And I click on the APPLY FILTERS button And I click on "Unverarbeitet" quick filter above the messages in Message directory page And I check that all displayed messages have "Arztmeldung" in grid Message Directory Type column + And I assign the Assignee to the message on Message Directory page + And I check that "Ad MIN" is assigned to the message on Message Directory page + And I click on the eye icon next for the first fetched message + Then I check if there are all needed buttons in HTML message file + And I close HTML message And I download message from Message Directory page And I verify if lab message file is downloaded correctly \ No newline at end of file From 22855306246bff1554dd54945e9fecf823c7b6a0 Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Thu, 3 Aug 2023 09:41:03 +0200 Subject: [PATCH 158/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. Verifying HTML file method has been changed. --- .../application/messages/MessagesDirectorySteps.java | 10 +++++----- .../resources/features/sanity/web/DemisWeb.feature | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java index 4929e17623c..015c9c83a22 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java @@ -462,22 +462,22 @@ public MessagesDirectorySteps( }); Then( - "^I check if there are any buttons in HTML message file$", + "^I check if there are any buttons from processed message in HTML message file$", () -> { webDriverHelpers.scrollToElement(HEADER_OF_ENTRY_LINK); - softly.assertTrue( + softly.assertFalse( webDriverHelpers.isElementPresent(MESSAGE_DELETE_BUTTON), "Delete message is available!"); softly.assertAll(); - softly.assertTrue( + softly.assertFalse( webDriverHelpers.isElementPresent(MARK_AS_UNCLEAR_BUTTON), "Delete message is available!"); softly.assertAll(); - softly.assertTrue( + softly.assertFalse( webDriverHelpers.isElementPresent(MARK_AS_FORWARDED_BUTTON), "Delete message is available!"); softly.assertAll(); - softly.assertTrue( + softly.assertFalse( webDriverHelpers.isElementPresent(SEND_TO_ANOTHER_ORGANIZATION_BUTTON), "Delete message is available!"); softly.assertAll(); diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index 0118d903ed1..3629d63beed 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -636,7 +636,7 @@ Scenario: Create and send laboratory request via Demis And I click on "Verarbeitet" quick filter above the messages in Message directory page And I check that all displayed messages have "Arztmeldung" in grid Message Directory Type column And I click on the eye icon next for the first fetched message - Then I check if there are any buttons in HTML message file + Then I check if there are any buttons from processed message in HTML message file And I close HTML message And I download message from Message Directory page And I verify if lab message file is downloaded correctly From 6c363685c3425bd36bad428ff44246a1e5358526 Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Thu, 3 Aug 2023 10:47:23 +0200 Subject: [PATCH 159/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. Download message method has been changed. --- .../messages/MessagesDirectoryPage.java | 3 ++- .../messages/MessagesDirectorySteps.java | 17 +++++++++++++---- .../features/sanity/web/DemisWeb.feature | 4 ++-- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java index 5226358e5ac..18d380c00ff 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/messages/MessagesDirectoryPage.java @@ -163,7 +163,8 @@ public static By getProcessStatusByIndex(int index) { public static final By EXPOSURE_INVESTIGATION_HEADER = By.cssSelector("[location='locExposureInvestigationHeading'] div"); public static final By ADD_VACCINATION_BUTTON = By.id("physiciansReportCaseAddVaccination"); - public static final By DOWNLOAD_BUTTON = By.xpath("//table/tbody/tr[1]/td[15]/div"); + public static final By DOWNLOAD_PROCESSED_BUTTON = By.xpath("//table/tbody/tr[1]/td[15]/div"); + public static final By DOWNLOAD_UNPROCESSED_BUTTON = By.xpath("//table/tbody/tr[1]/td[16]/div"); public static final By GRID_MESSAGE_UUID_TITLE = By.cssSelector("tr:nth-of-type(1) > td:nth-of-type(2) a"); public static final By ASSIGN_BUTTON = By.xpath("//table/tbody/tr[1]/td[14]/div"); diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java index 015c9c83a22..54c21e2b6c2 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java @@ -396,10 +396,19 @@ public MessagesDirectorySteps( }); And( - "^I download message from Message Directory page$", - () -> { - webDriverHelpers.scrollToElement(DOWNLOAD_BUTTON); - webDriverHelpers.clickOnWebElementBySelector(DOWNLOAD_BUTTON); + "I download {string} message from Message Directory page", + (String message) -> { + switch (message) { + case "processed": + webDriverHelpers.scrollToElement(DOWNLOAD_PROCESSED_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(DOWNLOAD_PROCESSED_BUTTON); + break; + case "unprocessed": + webDriverHelpers.scrollToElement(DOWNLOAD_UNPROCESSED_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(DOWNLOAD_UNPROCESSED_BUTTON); + break; + } + TimeUnit.SECONDS.sleep(5); // wait for download }); diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature index 3629d63beed..796d6654fc6 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/DemisWeb.feature @@ -638,7 +638,7 @@ Scenario: Create and send laboratory request via Demis And I click on the eye icon next for the first fetched message Then I check if there are any buttons from processed message in HTML message file And I close HTML message - And I download message from Message Directory page + And I download "processed" message from Message Directory page And I verify if lab message file is downloaded correctly @tmsLink=SORQA-1024 @env_d2s @LoginKeycloak @@ -659,5 +659,5 @@ Scenario: Create and send laboratory request via Demis And I click on the eye icon next for the first fetched message Then I check if there are all needed buttons in HTML message file And I close HTML message - And I download message from Message Directory page + And I download "unprocessed" message from Message Directory page And I verify if lab message file is downloaded correctly \ No newline at end of file From dad1c335f3576e24de3f94e2309a39abe89d854c Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Thu, 3 Aug 2023 12:26:26 +0300 Subject: [PATCH 160/174] #12025 - Add an environment list for the mobile app - update Android database version --- .../de/symeda/sormas/app/backend/common/DatabaseHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java index a941f5b16da..c6e1ec2a581 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java @@ -188,7 +188,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { public static final String DATABASE_NAME = "sormas.db"; // any time you make changes to your database objects, you may have to increase the database version - public static final int DATABASE_VERSION = 345; + public static final int DATABASE_VERSION = 346; private static DatabaseHelper instance = null; From 8009fec5908f14f47a4ec8aa48cc8860cc758dff Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Thu, 3 Aug 2023 11:27:36 +0200 Subject: [PATCH 161/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. Imports have been optimized. --- .../services/api/demis/DemisApiService.java | 6 +- .../steps/api/demisSteps/DemisSteps.java | 72 +++++++++++++++++-- .../messages/MessagesDirectorySteps.java | 55 +++++++++++++- 3 files changed, 126 insertions(+), 7 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java index 5bdea075db8..dbfc97b6616 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/demis/DemisApiService.java @@ -19,7 +19,11 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; -import okhttp3.*; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; import org.json.simple.JSONObject; import org.json.simple.JSONValue; import org.sormas.e2etests.envconfig.dto.demis.DemisData; diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java index 1e71842107f..23d53eeba35 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/api/demisSteps/DemisSteps.java @@ -27,21 +27,83 @@ import java.util.concurrent.atomic.AtomicInteger; import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.PERSON_ID_NAME_CONTACT_INFORMATION_LIKE_INPUT; +import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.DATE_OF_REPORT_INPUT; +import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.FIRST_NAME_INPUT; +import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.LAST_NAME_INPUT; import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.PLACE_OF_STAY_DISTRICT_COMBOBOX; import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.PLACE_OF_STAY_REGION_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.*; -import static org.sormas.e2etests.pages.application.cases.EditCasePage.*; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.ACTION_CANCEL; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.DISTRICT_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.PLACE_OF_STAY_OPTIONS; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.REGION_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.SAVE_POPUP_CONTENT; +import static org.sormas.e2etests.pages.application.cases.EditCasePage.UUID_INPUT; import static org.sormas.e2etests.pages.application.cases.EditContactsPage.RESPONSIBLE_DISTRICT_COMBOBOX; import static org.sormas.e2etests.pages.application.cases.EditContactsPage.RESPONSIBLE_REGION_COMBOBOX; -import static org.sormas.e2etests.pages.application.cases.EditContactsPage.*; +import static org.sormas.e2etests.pages.application.cases.EditContactsPage.getContactFirstAndLastName; import static org.sormas.e2etests.pages.application.contacts.ContactDirectoryPage.PERSON_LIKE_SEARCH_INPUT; import static org.sormas.e2etests.pages.application.entries.CreateNewTravelEntryPage.CREATE_NEW_CASE_RADIOBUTTON_DE; import static org.sormas.e2etests.pages.application.entries.CreateNewTravelEntryPage.CREATE_NEW_CONTACT_RADIOBUTTON_DE; import static org.sormas.e2etests.pages.application.entries.TravelEntryPage.NEW_PERSON_RADIOBUTTON_DE; import static org.sormas.e2etests.pages.application.entries.TravelEntryPage.PICK_OR_CREATE_PERSON_HEADER_DE; -import static org.sormas.e2etests.pages.application.events.CreateNewEventPage.*; +import static org.sormas.e2etests.pages.application.events.CreateNewEventPage.EVENT_DISTRICT; +import static org.sormas.e2etests.pages.application.events.CreateNewEventPage.EVENT_REGION; +import static org.sormas.e2etests.pages.application.events.CreateNewEventPage.NEW_EVENT_CREATED_DE_MESSAGE; +import static org.sormas.e2etests.pages.application.events.CreateNewEventPage.NEW_EVENT_RADIOBUTTON_DE_MESSAGE; +import static org.sormas.e2etests.pages.application.events.CreateNewEventPage.TITLE_INPUT; import static org.sormas.e2etests.pages.application.events.EventDirectoryPage.CHOOSE_OR_CREATE_EVENT_HEADER_DE; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.*; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.ALL_QUICK_FILTER_COUNTER; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.APPLY_FILTER_MESSAGE; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CASE_SAVED_POPUP_DE; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CHOOSE_OR_CREATE_ENTRY_HEADER; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CREATE_A_NEW_CASE_WITH_POSITIVE_TEST_CONTACT_HEADER_DE; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CREATE_A_NEW_CASE_WITH_POSITIVE_TEST_EVENT_PARTICIPANT_HEADER_DE; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CREATE_NEW_EVENT_PARTICIPANT_RADIOBUTTON_DE; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CREATE_NEW_PERSON_RADIOBUTTON_DE; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CREATE_NEW_SAMPLE_CHECKBOX; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.FIRST_PATHOGEN_LABORATORY_INPUT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.FORWARDED_QUICK_FILTER_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.FORWARDED_QUICK_FILTER_COUNTER; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.LABORATORY_DETAILS_INPUT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.LABORATORY_INPUT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGES_DETAILED_COLUMN_HEADERS; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGES_DETAILED_TABLE_ROWS; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGES_TABLE_DATA; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGE_DATE_FROM_INPUT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGE_EYE_ICON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGE_POPUP_HEADER; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGE_TIME_FROM_COMBOBOX; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGE_UUID_TEXT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MULTIPLE_SAMPLES_HEADER; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_CASE_FORM_DISEASE_VARIANT_INPUT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_FIRST_PATHOGEN_DISEASE_VARIANT_INPUT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_FIRST_PATHOGEN_LABORATORY_NAME; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_FIRST_PATHOGEN_TEST_TYPE_INPUT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_LABORATORY_NAME; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_SECOND_PATHOGEN_DISEASE_VARIANT_INPUT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_SECOND_PATHOGEN_LABORATORY_NAME; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_FORM_SECOND_PATHOGEN_TEST_TYPE_INPUT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEXT_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.PATIENT_BIRTHDAY_FROM_INPUT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.PATIENT_BIRTHDAY_TO_INPUT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.POPUP_CONFIRM_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.POPUP_WINDOW_BACK_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.POPUP_WINDOW_CANCEL_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.POPUP_WINDOW_SAVE_AND_OPEN_CASE_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.POPUP_WINDOW_SAVE_AND_OPEN_PHYSICIAN_REPORT_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.POPUP_WINDOW_SAVE_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.PROCESSED_QUICK_FILTER_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.PROCESSED_QUICK_FILTER_COUNTER; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.RELATED_FORWARDED_MESSAGE_HEADER; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.SAVE_POPUP_CONTENT_SECOND_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.SEARCH_MESSAGE_INPUT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.UNCLEAR_QUICK_FILTER_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.UNCLEAR_QUICK_FILTER_COUNTER; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.UNPROCESSED_QUICK_FILTER_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.UNPROCESSED_QUICK_FILTER_COUNTER; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.UPDATE_THE_DISEASE_VARIANT_HEADER; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.VERARBEITEN_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.checkMappedValueSelector; import static org.sormas.e2etests.pages.application.persons.PersonDirectoryPage.RESET_FILTERS_BUTTON; import static org.sormas.e2etests.pages.application.samples.CreateNewSamplePage.SAVE_SAMPLE_BUTTON; import static org.sormas.e2etests.pages.application.samples.CreateNewSamplePage.TYPE_OF_TEST_INPUT; diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java index 54c21e2b6c2..3dc458aeb12 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/messages/MessagesDirectorySteps.java @@ -21,7 +21,60 @@ import static org.sormas.e2etests.pages.application.cases.CreateNewCasePage.ACTION_CONFIRM_POPUP_BUTTON; import static org.sormas.e2etests.pages.application.cases.EditCasePage.SAMPLES_CARD_LABORATORY; -import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.*; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.ACTION_YES_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.ADD_VACCINATION_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.ASSIGNEE_LABEL; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.ASSIGN_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CASE_SAVED_POPUP_DE; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CLINICAL_MEASUREMENT_HEADER; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CLOSE_POPUP; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CREATE_NEW_CASE_POPUP_WINDOW_DE; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CREATE_NEW_SAMPLE_POPUP_WINDOW_DE; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.CURRENT_HOSPITALIZATION_HEADER; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.DOWNLOAD_PROCESSED_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.DOWNLOAD_UNPROCESSED_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.EDIT_ASSIGNEE_FILTER_SELECT_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.EXPOSURE_INVESTIGATION_HEADER; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.FETCH_MESSAGES_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.FETCH_MESSAGES_NULL_DATE; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.FETCH_MESSAGES_NULL_TIME_COMBOBOX; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.FIRST_RECORD_DISEASE_VARIANT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.FIRST_TIME_FETCH_MESSAGE_POPUP; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.FORWARDED_MESSAGE_COUNTER; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.GET_NEW_MESSAGES_POPUP; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.GRID_MESSAGE_UUID_TITLE; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.GRID_RESULTS_TYPE; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.HEADER_OF_ENTRY_LINK; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MARK_AS_FORWARDED_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MARK_AS_UNCLEAR_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGE_DELETE_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGE_DIRECTORY_HEADER_DE; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.MESSAGE_UUID_TEXT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_CASE_EMAIL_ADDRESS_INPUT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_CASE_PHONE_NUMBER_INPUT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_DATE_OF_REPORT_INPUT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_SPECIMEN_CONDITION_INPUT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_TESTED_DISEASE_INPUT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_TEST_RESULT_INPUT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_TEST_RESULT_VERIFIED_RADIOBUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEW_SAMPLE_TEST_RESULT_VERIFIED_SELECTED_VALUE; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NEXT_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.NO_NEW_REPORTS_POPUP; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.PATHOGEN_DETECTION_REPORTING_PROCESS_HEADER_DE; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.POPUP_CONFIRM_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.POPUP_WINDOW_CANCEL_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.POPUP_WINDOW_DISCARD_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.POPUP_WINDOW_SAVE_AND_OPEN_CASE_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.POPUP_WINDOW_SAVE_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.RESET_FILTER_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.SEARCH_MESSAGE_INPUT; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.SEND_TO_ANOTHER_ORGANIZATION_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.TOTAL_MESSAGE_COUNTER; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.TYPE_OF_MESSAGE_COMBOBOX; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.UNCLEAR_MESSAGE_COUNTER; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.UPDATE_CASE_DISEASE_VARIANT_CONFIRM_BUTTON; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.getProcessMessageButtonByIndex; +import static org.sormas.e2etests.pages.application.messages.MessagesDirectoryPage.getProcessStatusByIndex; @Slf4j public class MessagesDirectorySteps implements En { From d8403c6f5680edf3e402fd6cc8506ed7ce64f49c Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Thu, 3 Aug 2023 13:47:25 +0300 Subject: [PATCH 162/174] #12025 - Add an environment list for the mobile app - update DatabaseHelper queries --- .../app/backend/common/DatabaseHelper.java | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java index c6e1ec2a581..704cde9b961 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java @@ -3055,17 +3055,31 @@ public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int case 344: currentVersion = 344; getDao(Environment.class).executeRaw( - "CREATE TABLE environments(id integer primary key autoincrement, uuid VARCHAR(36) NOT NULL UNIQUE, " + "CREATE TABLE environments(id integer primary key autoincrement, uuid VARCHAR(36) NOT NULL, " + "changeDate TIMESTAMP NOT NULL, creationDate TIMESTAMP NOT NULL, lastOpenedDate TIMESTAMP, localChangeDate TIMESTAMP NOT NULL, modified INTEGER, " - + "snapshot INTEGER, reportDate TIMESTAMP NOT NULL, reportingUser_id BIGINT REFERENCES users(id), environmentName text, description text, " + + "snapshot INTEGER, reportDate TIMESTAMP, reportingUser_id BIGINT REFERENCES users(id), environmentName text, description text, " + "externalId varchar(255), responsibleUser_id BIGINT REFERENCES users(id), investigationStatus varchar(255), environmentMedia varchar(255), " + "waterType varchar(255), otherWaterType text, infrastructureDetails varchar(255), otherInfrastructureDetails text, waterUse text, " + "otherWaterUse text, location_id BIGINT, UNIQUE(snapshot, uuid));"); case 345: currentVersion = 345; - getDao(EnvironmentDao.class).executeRaw("ALTER TABLE environments uuid VARCHAR(36) NOT NULL UNIQUE"); - getDao(EnvironmentDao.class).executeRaw("ALTER TABLE environments reportDate TIMESTAMP NOT NULL"); + getDao(Environment.class).executeRaw("ALTER TABLE environments RENAME TO tmp_environments;"); + getDao(Environment.class).executeRaw( + "CREATE TABLE environments(id integer primary key autoincrement, uuid VARCHAR(36) NOT NULL UNIQUE, " + + "changeDate TIMESTAMP NOT NULL, creationDate TIMESTAMP NOT NULL, lastOpenedDate TIMESTAMP, localChangeDate TIMESTAMP NOT NULL, modified INTEGER, " + + "snapshot INTEGER, reportDate TIMESTAMP NOT NULL, reportingUser_id BIGINT REFERENCES users(id), environmentName text, description text, " + + "externalId varchar(255), responsibleUser_id BIGINT REFERENCES users(id), investigationStatus varchar(255), environmentMedia varchar(255), " + + "waterType varchar(255), otherWaterType text, infrastructureDetails varchar(255), otherInfrastructureDetails text, waterUse text, " + + "otherWaterUse text, location_id BIGINT, UNIQUE(snapshot, uuid));"); + getDao(Environment.class).executeRaw( + "INSERT INTO environments (uuid, changeDate, creationDate, lastOpenedDate, localChangeDate, modified, " + + "snapshot, reportDate, reportingUser_id, environmentName, description, externalId, responsibleUser_id, investigationStatus, environmentMedia, " + + "waterType, otherWaterType, infrastructureDetails, otherInfrastructureDetails, waterUse, otherWaterUse, location_id, id) " + + "SELECT uuid, changeDate, creationDate, lastOpenedDate, localChangeDate, modified, " + + "snapshot, reportDate, reportingUser_id, environmentName, description, externalId, responsibleUser_id, investigationStatus, environmentMedia, " + + "waterType, otherWaterType, infrastructureDetails, otherInfrastructureDetails, waterUse, otherWaterUse, location_id, id FROM tmp_environments"); + getDao(Environment.class).executeRaw("DROP TABLE tmp_environments"); // ATTENTION: break should only be done after last version break; From 728358a9c01878c05457ab4c1a308e90d45a684b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=A9=20Strysewske?= Date: Thu, 3 Aug 2023 13:56:39 +0200 Subject: [PATCH 163/174] #12332 - Remove unsupported feature config --- .../de/symeda/sormas/app/backend/common/DatabaseHelper.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java index 704cde9b961..1991f48b4a9 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java @@ -188,7 +188,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { public static final String DATABASE_NAME = "sormas.db"; // any time you make changes to your database objects, you may have to increase the database version - public static final int DATABASE_VERSION = 346; + public static final int DATABASE_VERSION = 347; private static DatabaseHelper instance = null; @@ -3081,6 +3081,10 @@ public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int + "waterType, otherWaterType, infrastructureDetails, otherInfrastructureDetails, waterUse, otherWaterUse, location_id, id FROM tmp_environments"); getDao(Environment.class).executeRaw("DROP TABLE tmp_environments"); + case 346: + currentVersion = 346; + getDao(FeatureConfiguration.class).executeRaw("DELETE FROM featureConfiguration WHERE featureType = 'DASHBOARD';"); + // ATTENTION: break should only be done after last version break; From 837ff0dab60b793b3620f08635283c10484bf10f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=A9=20Strysewske?= Date: Thu, 3 Aug 2023 14:16:56 +0200 Subject: [PATCH 164/174] New Crowdin updates (#12309) * New translations strings.properties (French, Tunisia) * New translations captions.properties (Romanian) * New translations captions.properties (Spanish) * New translations captions.properties (Arabic) * New translations captions.properties (Czech) * New translations captions.properties (German) * New translations captions.properties (Finnish) * New translations captions.properties (Italian) * New translations captions.properties (Japanese) * New translations captions.properties (Dutch) * New translations captions.properties (Norwegian) * New translations captions.properties (Polish) * New translations captions.properties (Portuguese) * New translations captions.properties (Russian) * New translations captions.properties (Swedish) * New translations captions.properties (Turkish) * New translations captions.properties (Ukrainian) * New translations captions.properties (Chinese Simplified) * New translations captions.properties (Urdu (Pakistan)) * New translations captions.properties (Croatian) * New translations captions.properties (Hindi) * New translations captions.properties (Filipino) * New translations captions.properties (Fijian) * New translations captions.properties (Swahili) * New translations captions.properties (German, Switzerland) * New translations captions.properties (Nepali) * New translations captions.properties (French, Switzerland) * New translations captions.properties (Italian, Switzerland) * New translations captions.properties (Dari) * New translations captions.properties (Pashto) * New translations captions.properties (Spanish, Cuba) * New translations captions.properties (English, Afghanistan) * New translations captions.properties (English, Nigeria) * New translations captions.properties (English, Ghana) * New translations captions.properties (French, Congo) * New translations captions.properties (French, Tunisia) * New translations strings.properties (Spanish, Cuba) * New translations captions.properties (Spanish, Cuba) * New translations captions.properties (Urdu (Pakistan)) * New translations enum.properties (German) * New translations strings.properties (Urdu (Pakistan)) * New translations captions.properties (German) * New translations strings.properties (German) * New translations strings.properties (German) * New translations strings.properties (French) * New translations strings.properties (Romanian) * New translations strings.properties (Spanish) * New translations strings.properties (Arabic) * New translations strings.properties (Czech) * New translations strings.properties (German) * New translations strings.properties (Finnish) * New translations strings.properties (Italian) * New translations strings.properties (Japanese) * New translations strings.properties (Dutch) * New translations strings.properties (Norwegian) * New translations strings.properties (Polish) * New translations strings.properties (Portuguese) * New translations strings.properties (Russian) * New translations strings.properties (Swedish) * New translations strings.properties (Turkish) * New translations strings.properties (Ukrainian) * New translations strings.properties (Chinese Simplified) * New translations strings.properties (Urdu (Pakistan)) * New translations strings.properties (Croatian) * New translations strings.properties (Hindi) * New translations strings.properties (Filipino) * New translations strings.properties (Fijian) * New translations strings.properties (Swahili) * New translations strings.properties (German, Switzerland) * New translations strings.properties (Nepali) * New translations strings.properties (French, Switzerland) * New translations strings.properties (Italian, Switzerland) * New translations strings.properties (Dari) * New translations strings.properties (Pashto) * New translations strings.properties (Spanish, Cuba) * New translations strings.properties (English, Afghanistan) * New translations strings.properties (English, Nigeria) * New translations strings.properties (English, Ghana) * New translations strings.properties (French, Congo) * New translations strings.properties (French, Tunisia) * New translations strings.properties (French) * New translations strings.properties (Urdu (Pakistan)) * New translations strings.properties (Czech) * New translations strings.properties (Spanish, Cuba) * New translations strings.properties (French) * New translations strings.properties (Romanian) * New translations strings.properties (Spanish) * New translations strings.properties (Arabic) * New translations strings.properties (Czech) * New translations strings.properties (German) * New translations strings.properties (Finnish) * New translations strings.properties (Italian) * New translations strings.properties (Japanese) * New translations strings.properties (Dutch) * New translations strings.properties (Norwegian) * New translations strings.properties (Polish) * New translations strings.properties (Portuguese) * New translations strings.properties (Russian) * New translations strings.properties (Swedish) * New translations strings.properties (Turkish) * New translations strings.properties (Ukrainian) * New translations strings.properties (Chinese Simplified) * New translations strings.properties (Urdu (Pakistan)) * New translations strings.properties (Croatian) * New translations strings.properties (Hindi) * New translations strings.properties (Filipino) * New translations strings.properties (Fijian) * New translations strings.properties (Swahili) * New translations strings.properties (German, Switzerland) * New translations strings.properties (Nepali) * New translations strings.properties (French, Switzerland) * New translations strings.properties (Italian, Switzerland) * New translations strings.properties (Dari) * New translations strings.properties (Pashto) * New translations strings.properties (Spanish, Cuba) * New translations strings.properties (English, Afghanistan) * New translations strings.properties (English, Nigeria) * New translations strings.properties (English, Ghana) * New translations strings.properties (French, Congo) * New translations strings.properties (French, Tunisia) * New translations captions.properties (French) * New translations strings.properties (Urdu (Pakistan)) * New translations strings.properties (Urdu (Pakistan)) * New translations strings.properties (Spanish, Cuba) * New translations strings.properties (Spanish, Cuba) * New translations strings.properties (Czech) * New translations strings.properties (French) * New translations strings.properties (French) * New translations strings.xml (Romanian) * New translations strings.xml (French) * New translations strings.xml (Spanish) * New translations strings.xml (Arabic) * New translations strings.xml (Czech) * New translations strings.xml (German) * New translations strings.xml (Finnish) * New translations strings.xml (Italian) * New translations strings.xml (Japanese) * New translations strings.xml (Dutch) * New translations strings.xml (Norwegian) * New translations strings.xml (Polish) * New translations strings.xml (Portuguese) * New translations strings.xml (Russian) * New translations strings.xml (Swedish) * New translations strings.xml (Turkish) * New translations strings.xml (Ukrainian) * New translations strings.xml (Chinese Simplified) * New translations strings.xml (Urdu (Pakistan)) * New translations strings.xml (Croatian) * New translations strings.xml (Hindi) * New translations strings.xml (Filipino) * New translations strings.xml (Fijian) * New translations strings.xml (Swahili) * New translations strings.xml (German, Switzerland) * New translations strings.xml (Nepali) * New translations strings.xml (French, Switzerland) * New translations strings.xml (Italian, Switzerland) * New translations strings.xml (Dari) * New translations strings.xml (Pashto) * New translations strings.xml (Spanish, Cuba) * New translations strings.xml (English, Afghanistan) * New translations strings.xml (English, Nigeria) * New translations strings.xml (English, Ghana) * New translations strings.xml (French, Congo) * New translations strings.xml (French, Tunisia) * New translations strings.xml (Urdu (Pakistan)) * New translations strings.xml (Spanish, Cuba) * New translations captions.properties (French) * New translations captions.properties (Romanian) * New translations captions.properties (Spanish) * New translations captions.properties (Arabic) * New translations captions.properties (Czech) * New translations captions.properties (German) * New translations captions.properties (Finnish) * New translations captions.properties (Italian) * New translations captions.properties (Japanese) * New translations captions.properties (Dutch) * New translations captions.properties (Norwegian) * New translations captions.properties (Polish) * New translations captions.properties (Portuguese) * New translations captions.properties (Russian) * New translations captions.properties (Swedish) * New translations captions.properties (Turkish) * New translations captions.properties (Ukrainian) * New translations captions.properties (Chinese Simplified) * New translations captions.properties (Urdu (Pakistan)) * New translations captions.properties (Croatian) * New translations captions.properties (Hindi) * New translations captions.properties (Filipino) * New translations captions.properties (Fijian) * New translations captions.properties (Swahili) * New translations captions.properties (German, Switzerland) * New translations captions.properties (Nepali) * New translations captions.properties (French, Switzerland) * New translations captions.properties (Italian, Switzerland) * New translations captions.properties (Dari) * New translations captions.properties (Pashto) * New translations captions.properties (Spanish, Cuba) * New translations captions.properties (English, Afghanistan) * New translations captions.properties (English, Nigeria) * New translations captions.properties (English, Ghana) * New translations captions.properties (French, Congo) * New translations captions.properties (French, Tunisia) * New translations strings.properties (Czech) * New translations captions.properties (Czech) * New translations captions.properties (Urdu (Pakistan)) * New translations strings.properties (Czech) * New translations enum.properties (Czech) * New translations captions.properties (Spanish, Cuba) * New translations strings.properties (French) * New translations strings.properties (Czech) * New translations strings.properties (Romanian) * New translations strings.properties (Spanish) * New translations strings.properties (Arabic) * New translations strings.properties (German) * New translations strings.properties (Finnish) * New translations strings.properties (Italian) * New translations strings.properties (Japanese) * New translations strings.properties (Dutch) * New translations strings.properties (Norwegian) * New translations strings.properties (Polish) * New translations strings.properties (Portuguese) * New translations strings.properties (Russian) * New translations strings.properties (Swedish) * New translations strings.properties (Turkish) * New translations strings.properties (Ukrainian) * New translations strings.properties (Chinese Simplified) * New translations strings.properties (Urdu (Pakistan)) * New translations strings.properties (Croatian) * New translations strings.properties (Hindi) * New translations strings.properties (Filipino) * New translations strings.properties (Fijian) * New translations strings.properties (Swahili) * New translations strings.properties (German, Switzerland) * New translations strings.properties (Nepali) * New translations strings.properties (French, Switzerland) * New translations strings.properties (Italian, Switzerland) * New translations strings.properties (Dari) * New translations strings.properties (Pashto) * New translations strings.properties (Spanish, Cuba) * New translations strings.properties (English, Afghanistan) * New translations strings.properties (English, Nigeria) * New translations strings.properties (English, Ghana) * New translations strings.properties (French, Congo) * New translations strings.properties (French, Tunisia) * New translations strings.properties (Czech) * New translations strings.properties (Urdu (Pakistan)) * New translations strings.properties (Spanish, Cuba) --- .../main/resources/captions_ar-SA.properties | 1 + .../main/resources/captions_cs-CZ.properties | 1 + .../main/resources/captions_de-CH.properties | 1 + .../main/resources/captions_de-DE.properties | 1 + .../main/resources/captions_en-AF.properties | 1 + .../main/resources/captions_en-GH.properties | 1 + .../main/resources/captions_en-NG.properties | 1 + .../main/resources/captions_es-CU.properties | 1 + .../main/resources/captions_es-ES.properties | 1 + .../main/resources/captions_fa-AF.properties | 1 + .../main/resources/captions_fi-FI.properties | 1 + .../main/resources/captions_fil-PH.properties | 1 + .../main/resources/captions_fj-FJ.properties | 1 + .../main/resources/captions_fr-CD.properties | 1 + .../main/resources/captions_fr-CH.properties | 1 + .../main/resources/captions_fr-FR.properties | 1 + .../main/resources/captions_fr-TN.properties | 1 + .../main/resources/captions_hi-IN.properties | 1 + .../main/resources/captions_hr-HR.properties | 1 + .../main/resources/captions_it-CH.properties | 1 + .../main/resources/captions_it-IT.properties | 1 + .../main/resources/captions_ja-JP.properties | 1 + .../main/resources/captions_ne-NP.properties | 1 + .../main/resources/captions_nl-NL.properties | 1 + .../main/resources/captions_no-NO.properties | 1 + .../main/resources/captions_pl-PL.properties | 1 + .../main/resources/captions_ps-AF.properties | 1 + .../main/resources/captions_pt-PT.properties | 1 + .../main/resources/captions_ro-RO.properties | 1 + .../main/resources/captions_ru-RU.properties | 1 + .../main/resources/captions_sv-SE.properties | 1 + .../main/resources/captions_sw-KE.properties | 1 + .../main/resources/captions_tr-TR.properties | 1 + .../main/resources/captions_uk-UA.properties | 1 + .../main/resources/captions_ur-PK.properties | 1 + .../main/resources/captions_zh-CN.properties | 1 + .../src/main/resources/enum_cs-CZ.properties | 32 +++--- .../main/resources/strings_ar-SA.properties | 13 ++- .../main/resources/strings_cs-CZ.properties | 97 ++++++++++--------- .../main/resources/strings_de-CH.properties | 13 ++- .../main/resources/strings_de-DE.properties | 13 ++- .../main/resources/strings_en-AF.properties | 13 ++- .../main/resources/strings_en-GH.properties | 13 ++- .../main/resources/strings_en-NG.properties | 13 ++- .../main/resources/strings_es-CU.properties | 13 ++- .../main/resources/strings_es-ES.properties | 13 ++- .../main/resources/strings_fa-AF.properties | 13 ++- .../main/resources/strings_fi-FI.properties | 13 ++- .../main/resources/strings_fil-PH.properties | 13 ++- .../main/resources/strings_fj-FJ.properties | 13 ++- .../main/resources/strings_fr-CD.properties | 13 ++- .../main/resources/strings_fr-CH.properties | 13 ++- .../main/resources/strings_fr-FR.properties | 41 ++++---- .../main/resources/strings_fr-TN.properties | 13 ++- .../main/resources/strings_hi-IN.properties | 13 ++- .../main/resources/strings_hr-HR.properties | 13 ++- .../main/resources/strings_it-CH.properties | 13 ++- .../main/resources/strings_it-IT.properties | 13 ++- .../main/resources/strings_ja-JP.properties | 13 ++- .../main/resources/strings_ne-NP.properties | 13 ++- .../main/resources/strings_nl-NL.properties | 13 ++- .../main/resources/strings_no-NO.properties | 13 ++- .../main/resources/strings_pl-PL.properties | 13 ++- .../main/resources/strings_ps-AF.properties | 13 ++- .../main/resources/strings_pt-PT.properties | 13 ++- .../main/resources/strings_ro-RO.properties | 13 ++- .../main/resources/strings_ru-RU.properties | 13 ++- .../main/resources/strings_sv-SE.properties | 13 ++- .../main/resources/strings_sw-KE.properties | 13 ++- .../main/resources/strings_tr-TR.properties | 13 ++- .../main/resources/strings_uk-UA.properties | 13 ++- .../main/resources/strings_ur-PK.properties | 13 ++- .../main/resources/strings_zh-CN.properties | 13 ++- .../src/main/res/values-ar-rSA/strings.xml | 3 + .../src/main/res/values-cs-rCZ/strings.xml | 3 + .../src/main/res/values-de-rCH/strings.xml | 3 + .../src/main/res/values-de-rDE/strings.xml | 3 + .../src/main/res/values-en-rAF/strings.xml | 3 + .../src/main/res/values-en-rGH/strings.xml | 3 + .../src/main/res/values-en-rNG/strings.xml | 3 + .../src/main/res/values-es-rCU/strings.xml | 3 + .../src/main/res/values-es-rES/strings.xml | 3 + .../src/main/res/values-fa-rAF/strings.xml | 3 + .../src/main/res/values-fi-rFI/strings.xml | 3 + .../src/main/res/values-fil-rPH/strings.xml | 3 + .../src/main/res/values-fj-rFJ/strings.xml | 3 + .../src/main/res/values-fr-rCD/strings.xml | 3 + .../src/main/res/values-fr-rCH/strings.xml | 3 + .../src/main/res/values-fr-rFR/strings.xml | 3 + .../src/main/res/values-fr-rTN/strings.xml | 3 + .../src/main/res/values-hi-rIN/strings.xml | 3 + .../src/main/res/values-hr-rHR/strings.xml | 3 + .../src/main/res/values-it-rCH/strings.xml | 3 + .../src/main/res/values-it-rIT/strings.xml | 3 + .../src/main/res/values-ja-rJP/strings.xml | 3 + .../src/main/res/values-ne-rNP/strings.xml | 3 + .../src/main/res/values-nl-rNL/strings.xml | 3 + .../src/main/res/values-no-rNO/strings.xml | 3 + .../src/main/res/values-pl-rPL/strings.xml | 3 + .../src/main/res/values-ps-rAF/strings.xml | 3 + .../src/main/res/values-pt-rPT/strings.xml | 3 + .../src/main/res/values-ro-rRO/strings.xml | 3 + .../src/main/res/values-ru-rRU/strings.xml | 3 + .../src/main/res/values-sv-rSE/strings.xml | 3 + .../src/main/res/values-sw-rKE/strings.xml | 3 + .../src/main/res/values-tr-rTR/strings.xml | 3 + .../src/main/res/values-uk-rUA/strings.xml | 3 + .../src/main/res/values-ur-rPK/strings.xml | 3 + .../src/main/res/values-zh-rCN/strings.xml | 3 + 109 files changed, 540 insertions(+), 216 deletions(-) diff --git a/sormas-api/src/main/resources/captions_ar-SA.properties b/sormas-api/src/main/resources/captions_ar-SA.properties index 8c716a1af0c..8d99aded9ad 100644 --- a/sormas-api/src/main/resources/captions_ar-SA.properties +++ b/sormas-api/src/main/resources/captions_ar-SA.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_cs-CZ.properties b/sormas-api/src/main/resources/captions_cs-CZ.properties index ede3aa2586d..ee9effd49ca 100644 --- a/sormas-api/src/main/resources/captions_cs-CZ.properties +++ b/sormas-api/src/main/resources/captions_cs-CZ.properties @@ -281,6 +281,7 @@ bulkContactClassification=Změnit klasifikaci kontaktů bulkContactOfficer=Změnit kontaktní osobu bulkDelete=Vymazat bulkDisease=Změnit chorobu +bulkDiseaseVariant=Změnit variantu choroby bulkEdit=Upravit... bulkEventInvestigationStatus=Změnit stav vyšetřování události bulkEventManagementStatus=Změnit stav řízení událostí diff --git a/sormas-api/src/main/resources/captions_de-CH.properties b/sormas-api/src/main/resources/captions_de-CH.properties index 7df84ed1d69..4a8a793337a 100644 --- a/sormas-api/src/main/resources/captions_de-CH.properties +++ b/sormas-api/src/main/resources/captions_de-CH.properties @@ -281,6 +281,7 @@ bulkContactClassification=Kontaktdefinitionskategorie ändern bulkContactOfficer=(Gesundheitsamts-)Mitarbeiter*in ändern bulkDelete=Löschen bulkDisease=Krankheit ändern +bulkDiseaseVariant=Change Disease variant bulkEdit=Bearbeiten... bulkEventInvestigationStatus=Status der Ereignisuntersuchung ändern bulkEventManagementStatus=Ereignis-Management-Status ändern diff --git a/sormas-api/src/main/resources/captions_de-DE.properties b/sormas-api/src/main/resources/captions_de-DE.properties index a9d1ba66e9b..48a471b2db5 100644 --- a/sormas-api/src/main/resources/captions_de-DE.properties +++ b/sormas-api/src/main/resources/captions_de-DE.properties @@ -281,6 +281,7 @@ bulkContactClassification=Kontaktdefinitionskategorie ändern bulkContactOfficer=Kontaktbeauftragte*n ändern bulkDelete=Löschen bulkDisease=Krankheit ändern +bulkDiseaseVariant=Change Disease variant bulkEdit=Bearbeiten... bulkEventInvestigationStatus=Status der Ereignisuntersuchung ändern bulkEventManagementStatus=Ereignis-Management-Status ändern diff --git a/sormas-api/src/main/resources/captions_en-AF.properties b/sormas-api/src/main/resources/captions_en-AF.properties index 6049044a931..30e056c7bd0 100644 --- a/sormas-api/src/main/resources/captions_en-AF.properties +++ b/sormas-api/src/main/resources/captions_en-AF.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_en-GH.properties b/sormas-api/src/main/resources/captions_en-GH.properties index 3c09d15fd10..d00ad02a6bd 100644 --- a/sormas-api/src/main/resources/captions_en-GH.properties +++ b/sormas-api/src/main/resources/captions_en-GH.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change district disease control officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_en-NG.properties b/sormas-api/src/main/resources/captions_en-NG.properties index 133ee77f16e..e740af8b3eb 100644 --- a/sormas-api/src/main/resources/captions_en-NG.properties +++ b/sormas-api/src/main/resources/captions_en-NG.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_es-CU.properties b/sormas-api/src/main/resources/captions_es-CU.properties index 3ef1bbfbdc9..ba223e54cec 100644 --- a/sormas-api/src/main/resources/captions_es-CU.properties +++ b/sormas-api/src/main/resources/captions_es-CU.properties @@ -281,6 +281,7 @@ bulkContactClassification=Cambiar clasificación de contactos bulkContactOfficer=Cambiar funcionario de contacto bulkDelete=Eliminar bulkDisease=Cambiar enfermedad +bulkDiseaseVariant=Cambiar variante de enfermedad bulkEdit=Editar... bulkEventInvestigationStatus=Cambiar estado de investigación del evento bulkEventManagementStatus=Cambiar estado de gestión de evento diff --git a/sormas-api/src/main/resources/captions_es-ES.properties b/sormas-api/src/main/resources/captions_es-ES.properties index 0026b5f73bb..93f3cdbebe6 100644 --- a/sormas-api/src/main/resources/captions_es-ES.properties +++ b/sormas-api/src/main/resources/captions_es-ES.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_fa-AF.properties b/sormas-api/src/main/resources/captions_fa-AF.properties index 59453be5f8e..46f9ff23b96 100644 --- a/sormas-api/src/main/resources/captions_fa-AF.properties +++ b/sormas-api/src/main/resources/captions_fa-AF.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_fi-FI.properties b/sormas-api/src/main/resources/captions_fi-FI.properties index 5ba38a4a059..79044ba49e8 100644 --- a/sormas-api/src/main/resources/captions_fi-FI.properties +++ b/sormas-api/src/main/resources/captions_fi-FI.properties @@ -281,6 +281,7 @@ bulkContactClassification=Vaihda kontaktin luokitus bulkContactOfficer=Vaihda kontaktivirkailija bulkDelete=Poista bulkDisease=Vaihda sairaus +bulkDiseaseVariant=Change Disease variant bulkEdit=Muokkaa... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_fil-PH.properties b/sormas-api/src/main/resources/captions_fil-PH.properties index ed91f071615..8e351b3e333 100644 --- a/sormas-api/src/main/resources/captions_fil-PH.properties +++ b/sormas-api/src/main/resources/captions_fil-PH.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_fj-FJ.properties b/sormas-api/src/main/resources/captions_fj-FJ.properties index ed91f071615..8e351b3e333 100644 --- a/sormas-api/src/main/resources/captions_fj-FJ.properties +++ b/sormas-api/src/main/resources/captions_fj-FJ.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_fr-CD.properties b/sormas-api/src/main/resources/captions_fr-CD.properties index 909d275f877..dc8680ec4db 100644 --- a/sormas-api/src/main/resources/captions_fr-CD.properties +++ b/sormas-api/src/main/resources/captions_fr-CD.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_fr-CH.properties b/sormas-api/src/main/resources/captions_fr-CH.properties index 253f0846f64..0102e567c13 100644 --- a/sormas-api/src/main/resources/captions_fr-CH.properties +++ b/sormas-api/src/main/resources/captions_fr-CH.properties @@ -281,6 +281,7 @@ bulkContactClassification=Changer la classification de contact bulkContactOfficer=Changer l'agent de contact bulkDelete=Supprimer bulkDisease=Changer la maladie +bulkDiseaseVariant=Change Disease variant bulkEdit=Modifier... bulkEventInvestigationStatus=Modifier le statut de l'enquête de l'événement bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_fr-FR.properties b/sormas-api/src/main/resources/captions_fr-FR.properties index 852b0ba3ab2..45b0c5269d7 100644 --- a/sormas-api/src/main/resources/captions_fr-FR.properties +++ b/sormas-api/src/main/resources/captions_fr-FR.properties @@ -281,6 +281,7 @@ bulkContactClassification=Modifier la classification des contacts bulkContactOfficer=Modifier l'agent de contact bulkDelete=Supprimer bulkDisease=Changer de maladie +bulkDiseaseVariant=Change Disease variant bulkEdit=Modifier... bulkEventInvestigationStatus=Modifier le statut de l'enquête de l'événement bulkEventManagementStatus=Modifier le statut de gestion des événements diff --git a/sormas-api/src/main/resources/captions_fr-TN.properties b/sormas-api/src/main/resources/captions_fr-TN.properties index 59ba2b6cb80..58328ad3d9b 100644 --- a/sormas-api/src/main/resources/captions_fr-TN.properties +++ b/sormas-api/src/main/resources/captions_fr-TN.properties @@ -281,6 +281,7 @@ bulkContactClassification=Modifier la classification des contacts bulkContactOfficer=Modifier l'agent de contact bulkDelete=Supprimer bulkDisease=Changer de maladie +bulkDiseaseVariant=Change Disease variant bulkEdit=Modifier... bulkEventInvestigationStatus=Modifier le statut de l'enquête de l'événement bulkEventManagementStatus=Modifier le statut de gestion des événements diff --git a/sormas-api/src/main/resources/captions_hi-IN.properties b/sormas-api/src/main/resources/captions_hi-IN.properties index ed91f071615..8e351b3e333 100644 --- a/sormas-api/src/main/resources/captions_hi-IN.properties +++ b/sormas-api/src/main/resources/captions_hi-IN.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_hr-HR.properties b/sormas-api/src/main/resources/captions_hr-HR.properties index ed91f071615..8e351b3e333 100644 --- a/sormas-api/src/main/resources/captions_hr-HR.properties +++ b/sormas-api/src/main/resources/captions_hr-HR.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_it-CH.properties b/sormas-api/src/main/resources/captions_it-CH.properties index e21f9f496fe..c7e28827803 100644 --- a/sormas-api/src/main/resources/captions_it-CH.properties +++ b/sormas-api/src/main/resources/captions_it-CH.properties @@ -281,6 +281,7 @@ bulkContactClassification=Cambia classificazione contatto bulkContactOfficer=Cambia referente bulkDelete=Elimina bulkDisease=Cambia malattia +bulkDiseaseVariant=Change Disease variant bulkEdit=Modifica... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_it-IT.properties b/sormas-api/src/main/resources/captions_it-IT.properties index fb7922914a5..f9830b2259a 100644 --- a/sormas-api/src/main/resources/captions_it-IT.properties +++ b/sormas-api/src/main/resources/captions_it-IT.properties @@ -281,6 +281,7 @@ bulkContactClassification=Cambia classificazione contatto bulkContactOfficer=Cambia referente bulkDelete=Elimina bulkDisease=Cambia malattia +bulkDiseaseVariant=Change Disease variant bulkEdit=Modifica... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_ja-JP.properties b/sormas-api/src/main/resources/captions_ja-JP.properties index ed91f071615..8e351b3e333 100644 --- a/sormas-api/src/main/resources/captions_ja-JP.properties +++ b/sormas-api/src/main/resources/captions_ja-JP.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_ne-NP.properties b/sormas-api/src/main/resources/captions_ne-NP.properties index 8c716a1af0c..8d99aded9ad 100644 --- a/sormas-api/src/main/resources/captions_ne-NP.properties +++ b/sormas-api/src/main/resources/captions_ne-NP.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_nl-NL.properties b/sormas-api/src/main/resources/captions_nl-NL.properties index f5959afc553..28cf7cc2753 100644 --- a/sormas-api/src/main/resources/captions_nl-NL.properties +++ b/sormas-api/src/main/resources/captions_nl-NL.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_no-NO.properties b/sormas-api/src/main/resources/captions_no-NO.properties index ed91f071615..8e351b3e333 100644 --- a/sormas-api/src/main/resources/captions_no-NO.properties +++ b/sormas-api/src/main/resources/captions_no-NO.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_pl-PL.properties b/sormas-api/src/main/resources/captions_pl-PL.properties index 4fb14aedf02..42847a4cd97 100644 --- a/sormas-api/src/main/resources/captions_pl-PL.properties +++ b/sormas-api/src/main/resources/captions_pl-PL.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Usuń bulkDisease=Zmień chorobę +bulkDiseaseVariant=Change Disease variant bulkEdit=Edytuj... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_ps-AF.properties b/sormas-api/src/main/resources/captions_ps-AF.properties index cb123018025..6a4e2913a67 100644 --- a/sormas-api/src/main/resources/captions_ps-AF.properties +++ b/sormas-api/src/main/resources/captions_ps-AF.properties @@ -281,6 +281,7 @@ bulkContactClassification=د تماس نیولو تقسیم بندی بدلول bulkContactOfficer=د تماس کارکونکې بدلول bulkDelete=له منځه وړل bulkDisease=د ناروغې بدلول +bulkDiseaseVariant=Change Disease variant bulkEdit=صحیح کول\nکره کتنه... bulkEventInvestigationStatus=د پیښی د بررسۍ حالت بدلولون bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_pt-PT.properties b/sormas-api/src/main/resources/captions_pt-PT.properties index ab3bb172799..cd0fef61028 100644 --- a/sormas-api/src/main/resources/captions_pt-PT.properties +++ b/sormas-api/src/main/resources/captions_pt-PT.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_ro-RO.properties b/sormas-api/src/main/resources/captions_ro-RO.properties index ed91f071615..8e351b3e333 100644 --- a/sormas-api/src/main/resources/captions_ro-RO.properties +++ b/sormas-api/src/main/resources/captions_ro-RO.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_ru-RU.properties b/sormas-api/src/main/resources/captions_ru-RU.properties index 7708a26d17f..4da62cef3c8 100644 --- a/sormas-api/src/main/resources/captions_ru-RU.properties +++ b/sormas-api/src/main/resources/captions_ru-RU.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_sv-SE.properties b/sormas-api/src/main/resources/captions_sv-SE.properties index ed91f071615..8e351b3e333 100644 --- a/sormas-api/src/main/resources/captions_sv-SE.properties +++ b/sormas-api/src/main/resources/captions_sv-SE.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_sw-KE.properties b/sormas-api/src/main/resources/captions_sw-KE.properties index ed91f071615..8e351b3e333 100644 --- a/sormas-api/src/main/resources/captions_sw-KE.properties +++ b/sormas-api/src/main/resources/captions_sw-KE.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_tr-TR.properties b/sormas-api/src/main/resources/captions_tr-TR.properties index ed91f071615..8e351b3e333 100644 --- a/sormas-api/src/main/resources/captions_tr-TR.properties +++ b/sormas-api/src/main/resources/captions_tr-TR.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_uk-UA.properties b/sormas-api/src/main/resources/captions_uk-UA.properties index ed91f071615..8e351b3e333 100644 --- a/sormas-api/src/main/resources/captions_uk-UA.properties +++ b/sormas-api/src/main/resources/captions_uk-UA.properties @@ -281,6 +281,7 @@ bulkContactClassification=Change contact classification bulkContactOfficer=Change contact officer bulkDelete=Delete bulkDisease=Change Disease +bulkDiseaseVariant=Change Disease variant bulkEdit=Edit... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/captions_ur-PK.properties b/sormas-api/src/main/resources/captions_ur-PK.properties index 61dd080650f..7403b4dc16f 100644 --- a/sormas-api/src/main/resources/captions_ur-PK.properties +++ b/sormas-api/src/main/resources/captions_ur-PK.properties @@ -281,6 +281,7 @@ bulkContactClassification=رابطے کی درجہ بندی کو تبدیل کر bulkContactOfficer=رابطہ افسر کو تبدیل کریں bulkDelete=مٹا ديں bulkDisease=بیماری کو تبدیل کریں +bulkDiseaseVariant=بیماری کی قسم کو تبدیل کریں bulkEdit=ترمیم... bulkEventInvestigationStatus=تقریب کی تفتیش کی حالت کو تبدیل کریں bulkEventManagementStatus=تقریب کے انتظامات کی حالت کو تبدیل کریں diff --git a/sormas-api/src/main/resources/captions_zh-CN.properties b/sormas-api/src/main/resources/captions_zh-CN.properties index b4367b207fe..e48eda1e75c 100644 --- a/sormas-api/src/main/resources/captions_zh-CN.properties +++ b/sormas-api/src/main/resources/captions_zh-CN.properties @@ -281,6 +281,7 @@ bulkContactClassification=更改联系人分类 bulkContactOfficer=更改联系人 bulkDelete=删除 bulkDisease=改变疾病 +bulkDiseaseVariant=Change Disease variant bulkEdit=编辑... bulkEventInvestigationStatus=Change event investigation status bulkEventManagementStatus=Change event management status diff --git a/sormas-api/src/main/resources/enum_cs-CZ.properties b/sormas-api/src/main/resources/enum_cs-CZ.properties index caabadbcf14..15418983f54 100644 --- a/sormas-api/src/main/resources/enum_cs-CZ.properties +++ b/sormas-api/src/main/resources/enum_cs-CZ.properties @@ -1557,13 +1557,13 @@ UserRight.DOCUMENT_VIEW = Zobrazit existující dokumenty UserRight.DOCUMENT_UPLOAD = Nahrát dokumenty UserRight.DOCUMENT_DELETE = Odstranit dokumenty ze systému UserRight.PERSON_MERGE = Sloučit osoby -UserRight.ENVIRONMENT_VIEW = View existing environments -UserRight.ENVIRONMENT_CREATE = Create new environments -UserRight.ENVIRONMENT_EDIT = Edit existing environments -UserRight.ENVIRONMENT_ARCHIVE = Archive environments -UserRight.ENVIRONMENT_DELETE = Delete environments from the system -UserRight.ENVIRONMENT_IMPORT = Import environments -UserRight.ENVIRONMENT_EXPORT = Export environments +UserRight.ENVIRONMENT_VIEW = Zobrazit existující prostředí +UserRight.ENVIRONMENT_CREATE = Vytvořit nové prostředí +UserRight.ENVIRONMENT_EDIT = Upravit existující prostředí +UserRight.ENVIRONMENT_ARCHIVE = Archivovat prostředí +UserRight.ENVIRONMENT_DELETE = Odstranit prostředí ze systému +UserRight.ENVIRONMENT_IMPORT = Importovat prostředí +UserRight.ENVIRONMENT_EXPORT = Exportovat prostředí # UserRight descriptions UserRight.Desc.CASE_ARCHIVE = Může archivovat případy @@ -1706,7 +1706,7 @@ UserRight.Desc.EXTERNAL_SURVEILLANCE_SHARE = Umožňuje mazání případů nebo UserRight.Desc.EXTERNAL_SURVEILLANCE_DELETE = Umožňuje mazání případů nebo událostí v externích pozorovacích nástrojích. Aby se tak stalo, je nutné upravit uživatelská práva správně. UserRight.Desc.EXTERNAL_MESSAGE_VIEW = Může zobrazit načíst zprávy UserRight.Desc.EXTERNAL_MESSAGE_PROCESS = Může pracovat se zprávami -UserRight.Desc.EXTERNAL_MESSAGE_PUSH = Able to push external messages to the system +UserRight.Desc.EXTERNAL_MESSAGE_PUSH = Možnost odesílat externí zprávy do systému UserRight.Desc.EXTERNAL_MESSAGE_DELETE = Může smazat zprávy UserRight.Desc.CASE_SHARE = Může sdílet případy s celou zemí UserRight.Desc.PERFORM_BULK_OPERATIONS_EXTERNAL_MESSAGES = Může provádět hromadné operace v seznamu zpráv @@ -1743,12 +1743,12 @@ UserRight.Desc.DOCUMENT_VIEW = Může zobrazit existující dokumenty UserRight.Desc.DOCUMENT_UPLOAD = Může nahrát dokumenty UserRight.Desc.DOCUMENT_DELETE = Může odstranit dokumenty ze systému UserRight.Desc.PERSON_MERGE = Může sloučit osoby -UserRight.Desc.ENVIRONMENT_CREATE = Able to create new environments -UserRight.Desc.ENVIRONMENT_EDIT = Able to edit existing environments -UserRight.Desc.ENVIRONMENT_ARCHIVE = Able to archive environments -UserRight.Desc.ENVIRONMENT_DELETE = Able to delete environments from the system -UserRight.Desc.ENVIRONMENT_IMPORT = Able to import environments -UserRight.Desc.ENVIRONMENT_EXPORT = Able to export environments +UserRight.Desc.ENVIRONMENT_CREATE = Možnost vytvářet nové prostředí +UserRight.Desc.ENVIRONMENT_EDIT = Možnost upravit existující prostředí +UserRight.Desc.ENVIRONMENT_ARCHIVE = Možnost archivovat prostředí +UserRight.Desc.ENVIRONMENT_DELETE = Možnost odstranit prostředí ze systému +UserRight.Desc.ENVIRONMENT_IMPORT = Možnost importovat prostředí +UserRight.Desc.ENVIRONMENT_EXPORT = Možnost exportovat prostředí # UserRightGroup UserRightGroup.GENERAL = Obecné @@ -1757,7 +1757,7 @@ UserRightGroup.PERSON = Osoby UserRightGroup.CASE = Dohled nad případem UserRightGroup.CASE_MANAGEMENT = Správa případů UserRightGroup.PORT_HEALTH = Vstupní hygienická kontrola -UserRightGroup.CONTACT = Contact Surveillance +UserRightGroup.CONTACT = Kontaktní dozor UserRightGroup.VISIT = Následná opatření UserRightGroup.SAMPLE = Testování vzorku UserRightGroup.IMMUNIZATION = Imunizace @@ -1774,7 +1774,7 @@ UserRightGroup.USER = Uživatelé UserRightGroup.INFRASTRUCTURE = Infrastruktura UserRightGroup.CONFIGURATION = Konfigurace UserRightGroup.DOCUMENT = Dokumenty -UserRightGroup.ENVIRONMENT = Environments +UserRightGroup.ENVIRONMENT = Prostředí # Vaccination VaccinationStatus.UNKNOWN = Neznámý diff --git a/sormas-api/src/main/resources/strings_ar-SA.properties b/sormas-api/src/main/resources/strings_ar-SA.properties index 4b357d2941e..e4236d4d812 100644 --- a/sormas-api/src/main/resources/strings_ar-SA.properties +++ b/sormas-api/src/main/resources/strings_ar-SA.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Current Hospitalization headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_cs-CZ.properties b/sormas-api/src/main/resources/strings_cs-CZ.properties index 59ed987ff3a..3af7138c8c8 100644 --- a/sormas-api/src/main/resources/strings_cs-CZ.properties +++ b/sormas-api/src/main/resources/strings_cs-CZ.properties @@ -127,8 +127,8 @@ confirmationDearchiveCaseWithContacts = Dearchive related contacts along with th confirmationArchiveCases = Opravdu chcete archivovat všech %d vybraných případů? confirmationArchiveContact = Opravdu chcete archivovat tento kontakt? Toto jej neodstraní ze systému ani ze statistik, ale skryje pouze z běžného adresáře kontaktů. confirmationArchiveContacts = Opravdu chcete archivovat všech %d vybraných kontaktů? -confirmationArchiveEnvironment = Are you sure you want to archive this environment? This will not remove it from the system or any statistics, but only hide it from the normal environment directory. -confirmationArchiveEnvironments = Are you sure you want to archive all %d selected environments? +confirmationArchiveEnvironment = Opravdu chcete archivovat toto prostředí? Toto neodstraní ze systému ani ze statistik, ale skryje pouze z běžného adresáře prostředí. +confirmationArchiveEnvironments = Opravdu chcete archivovat všech %d vybraných prostředí? confirmationArchiveEvent = Opravdu chcete archivovat tuto událost? To ji neodstraní ze systému ani ze statistik, ale skryje pouze z běžného adresáře událostí. confirmationArchiveEvents = Jste si jisti, že chcete archivovat všech %d vybraných událostí? confirmationArchiveEventParticipant = Opravdu chcete archivovat tohoto účastníka události? Toto jej neodstraní ze systému ani ze statistik, ale skryje ho pouze ze seznamu účastníků událostí. @@ -145,14 +145,14 @@ confirmationDearchiveCases = Jste si jisti, že chcete vyjmout z archivu všech confirmationDearchiveContact = Opravdu chcete vyjmout z archivu tento kontakt? Tím se opět objeví v normálním adresáři kontaktů. confirmationDearchiveContacts = Opravdu chcete vyarchivovat všech %d vybraných kontaktů? confirmationDearchiveEnvironment = Are you sure you want to de-archive this environment? This will make it appear in the normal environment directory again. -confirmationDearchiveEnvironments = Are you sure you want to de-archive all %d selected environments? +confirmationDearchiveEnvironments = Opravdu chcete dearchivovat všech %d vybraných prostředí? confirmationDearchiveEvent = Jste si jisti, že chcete vyjmout z archivu tuto událost? Tato akce se znovu zobrazí v normální adresáři událostí. confirmationDearchiveEvents = Jste si jisti, že chcete vyjmout z archivu všech %d vybraných události? confirmationDearchiveEventParticipant = Opravdu chcete vyjmout z archivu tohoto účastníka? Ten se zobrazí znovu v seznamu účastníků běžné události. confirmationDearchiveEventGroup = Jste si jisti, že chcete vyjmout z archivu tuto skupinu událostí? Ta se znovu zobrazí v normální složce skupiny událostí. confirmationDeleteCases = Opravdu chcete odstranit všech %d vybraných případů?

Pokud se na ně odkazují jiná data, tyto odkazy budou odstraněny, které nelze automaticky vrátit zpět. confirmationDeleteContacts = Opravdu chcete odstranit všech %d vybraných případů?

Pokud se na ně odkazují jiná data, tyto odkazy budou odstraněny, které nelze automaticky vrátit zpět. -confirmationDeleteEntities = Are you sure you want to delete all %d selected %s?

If referenced by other data in the system, those references will be removed, which cannot be automatically undone. +confirmationDeleteEntities = Opravdu chcete odstranit všechny %d vybrané %s?

Pokud se na ně odkazují jiná data v systému, budou tyto odkazy odstraněny, které nelze automaticky vrátit. confirmationRestoreEntities = Opravdu chcete obnovit všech %d vybraných %s? confirmationDeleteEntity = Opravdu chcete smazat %s?

Pokud se na ně odkazují jiná data, tyto odkazy budou odstraněny, které nelze automaticky vrátit zpět. confirmationDeleteEntityWithDetails = Opravdu chcete smazat %s?
%s
Pokud se na ně odkazují jiná data, tyto odkazy budou odstraněny, což nelze automaticky vrátit zpět. @@ -538,10 +538,8 @@ headingExportFailed = Export selhal headingFatalities=Úmrtnost headingFileExists = Duplikovat soubor headingFilters = Filtry -headingFollowUpCanceled = Následná opatření byla zrušena headingStoppedFollowUp = Zastavena následná opatření headingFollowUpStatus = Stav následných opatření -headingFollowUpStatusChanged = Stav následných opatření byl změněn headingHealthConditions = Již existující podmínky headingHospitalization = Data o hospitalizaci headingPreviousHospitalizations = Předchozí hospitalizace @@ -771,8 +769,6 @@ headingCaution = Varování headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Odstranit imunizační vakcinaci headingDocumentCreated = Dokument vytvořen -headingUsersEnabled = Uživatelé povoleni -headingUsersDisabled = Uživatelé zakázáni headingConfirmUnclearLabMessage=Potvrzení nejasné headingConfirmManuallyForwardedLabMessage=Potvrzení přeposláno headingUpdateCaseWithNewDiseaseVariant=Aktualizovat variantu případové choroby @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Očkování immunizationRecoveryHeading = Uzdravení headingAutomaticDeletionStarted = Automatické smazání zahájeno headingBulkOperationProgress = Průběh hromadné operace +headingSomeContactsAlreadyInEvent = Některé kontakty jsou již propojeny s událostí # Info texts infoActivityAsCaseInvestigation = Prosím zdokumentujte VŠECHNY relevantní aktivity po infekci\: @@ -998,13 +995,13 @@ infoTasksWithMultipleJurisdictionsSelected = Vybrali jste úlohy, které jsou sp infoNoAccessToPersonEntities = Nemáte potřebná uživatelská práva k zobrazení záznamů spojených s osobami. infoDashboardFinalLaboratoryResult = Pokud má případ více vzorků, bere se v úvahu pouze konečný laboratorní výsledek vzorku s nejzazším datem odběru vzorku. infoBulkProcess = %d selected entries are currently being processed. This may take a while. The progress will be updated for each 20 entries that have been processed. -infoBulkProcessFinished = All selected entries have been processed\!
You can now close this window. -infoBulkProcessFinishedWithIneligibleItems = Bulk process has been successfully completed\!
However, some of the selected entries could not be processed, because they were not eligible. -infoBulkProcessFinishedWithSkipsOutsideJurisdiction = Bulk process has been successfully completed\!
However, some of the selected entries could not be processed, most likely because they were outside your jurisdiction. -infoBulkProcessFinishedWithSkips = Bulk process has been successfully completed\!
However, some of the selected entries could not be processed, most likely because they were outside your jurisdiction, already archived or not eligible. -infoBulkProcessNoEligibleEntries = Bulk process has been cancelled because there are no eligible entries for this operation\! -infoBulkProcessCancelled = Bulk process has been cancelled\!
All selected entries up until this point have been processed. You can now close this window. All not yet processed entries will still be selected. -infoBulkUnresponsiveWindowHint = Hint\: If the progress bar seems to be unresponsive and no progress is visible after a while, try to click this popup window or resize your browser window. +infoBulkProcessFinished = Všechny vybrané položky byly zpracovány\!
Nyní můžete toto okno zavřít. +infoBulkProcessFinishedWithIneligibleItems = Hromadný proces byl úspěšně dokončen\!
Některé z vybraných položek však nemohly být zpracovány, protože nebyly způsobilé. +infoBulkProcessFinishedWithSkipsOutsideJurisdiction = Hromadný proces byl úspěšně dokončen\!
Některé z vybraných položek však nemohly být zpracovány, s největší pravděpodobností proto, že byly mimo vaši jurisdikci. +infoBulkProcessFinishedWithSkips = Hromadný proces byl úspěšně dokončen\!
Některé z vybraných položek však nemohly být zpracovány, s největší pravděpodobností proto, že již byly archivovány nebo nejsou způsobilé. +infoBulkProcessNoEligibleEntries = Hromadný proces byl zrušen, protože pro tuto operaci nejsou žádné způsobilé položky\! +infoBulkProcessCancelled = Hromadný proces byl zrušen\!
Všechny vybrané položky až do zpracování tohoto bodu. Nyní můžete toto okno zavřít. Budou vybrány všechny dosud nezpracované položky. +infoBulkUnresponsiveWindowHint = Tip\: Pokud se ukazatel průběhu zdá být nereagující a po chvíli není vidět žádný průběh zkuste kliknout na toto vyskakovací okno nebo změnit velikost okna prohlížeče. # Messages messageActionOutsideJurisdictionDeletionDenied = Akce mimo jurisdikci uživatele nemůže být odstraněna @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = Všechny případy jsou již propojeny s vybrano messageAllCasesLinkedToEvent = Všechny případy byly propojeny s vybranou událostí. messageAllContactsAlreadyInEvent = Všechny kontakty jsou již propojeny s vybranou událostí. messageAllContactsLinkedToEvent = Všechny kontakty byly propojeny s vybranou událostí. +messageSomeContactsLinkedToEvent = Některé z vybraných kontaktů byly propojeny s vybranou událostí. messageAlreadyEventParticipant = Vybraná osoba je již definována jako účastník této události. messageAnimalContactsHint = Uveďte prosím odpověď týkající se všech zvířat (živých nebo mrtvých), jimž byla osoba přímo vystavena (např. při lovu, doteku, jídlem) během inkubační doby messageArchiveUndoneReasonMandatory = Přidejte prosím důvod pro vyjmutí z archivu @@ -1039,25 +1037,25 @@ messageCaseRelationToEventWithoutDisease=Není možné spojit případ s událos messageCaseSaved = Případ uložen messageCaseSavedClassificationChanged = Případ uložen. Klasifikace byla automaticky změněna na %s. messageCaseTransfered = Případ byl převeden do jiného zařízení -messageCasesNotDeleted = The cases mentioned in the above list of UUIDs could not be deleted. -messageCasesNotDeletedExternalReason = The cases mentioned in the above list of UUIDs could not be deleted because the communication with the reporting tool failed. -messageCasesDeleted = All selected eligible cases have been deleted -messageCaseOutsideJurisdictionDeletionDenied = The case outside user's jurisdiction cannot be deleted +messageCasesNotDeleted = Případy uvedené ve výše uvedeném seznamu UUID nelze odstranit. +messageCasesNotDeletedExternalReason = Případy uvedené ve výše uvedeném seznamu UUID nemohly být odstraněny, protože komunikace s oznamovacím nástrojem selhala. +messageCasesDeleted = Všechny vybrané způsobilé případy byly odstraněny +messageCaseOutsideJurisdictionDeletionDenied = Nelze odstranit případ mimo jurisdikci uživatele messageCasesMerged = Případy sloučeny a duplicitní případ odstraněn. messageCasesRestored = Všechny vybrané případy byly obnoveny -messageContactsNotRestored = The contacts mentioned in the above list of UUIDs could not be restored. +messageContactsNotRestored = Kontakty uvedené ve výše uvedeném seznamu UUID nelze obnovit. messageContactsRestored = Všechny vybrané kontakty byly obnoveny -messageEventsNotRestored = The events mentioned in the above list of UUIDs could not be restored. +messageEventsNotRestored = Události uvedené ve výše uvedeném seznamu UUID nelze obnovit. messageEventsRestored = Všechny vybrané události byly obnoveny -messageEventParticipantsNotRestored = The event participants mentioned in the above list of UUIDs could not be restored. +messageEventParticipantsNotRestored = Účastníky události uvedení na výše uvedeném seznamu UUID nelze obnovit. messageEventParticipantsRestored = Všichni vybraní účastníci události byli obnoveni -messageImmunizationsNotDeleted = The immunizations mentioned in the above list of UUIDs could not be deleted. -messageImmunizationsDeleted = All selected eligible immunizations have been deleted -messageImmunizationsNotRestored = The immunizations mentioned in the above list of UUIDs could not be restored. +messageImmunizationsNotDeleted = Imunizace uvedené ve výše uvedeném seznamu UUID nelze odstranit. +messageImmunizationsDeleted = Všechny vybrané způsobilé imunizace byly odstraněny +messageImmunizationsNotRestored = Imunizace uvedené ve výše uvedeném seznamu UUID nelze obnovit. messageImmunizationsRestored = Všechny vybrané imunizace byly obnoveny -messageSamplesNotRestored = The samples mentioned in the above list of UUIDs could not be restored. +messageSamplesNotRestored = Vzorky uvedené ve výše uvedeném seznamu UUID nelze obnovit. messageSamplesRestored = Všechny vybrané vzorky byly obnoveny -messageTravelEntriesNotRestored = The travel entries mentioned in the above list of UUIDs could not be restored. +messageTravelEntriesNotRestored = Místa vstupu uvedené ve výše uvedeném seznamu UUID nelze obnovit. messageTravelEntriesRestored = All selected travel entries have been restored messageCasesNotRestored = Případy uvedené ve výše uvedeném seznamu UUID nelze obnovit. messageChangePathogenTestResult = Výsledek testu tohoto patogenu se liší od současného celkového výsledku testu patogenu vzorku. Chcete aktualizovat výsledek na %s? @@ -1106,6 +1104,8 @@ messageEventGroupCreated = Nová skupina událostí vytvořena messageEventLinkedAsSuperordinate = Vybraná událost byla úspěšně propojena s touto událostí jako její superordinate událost messageEventLinkedAsSubordinate = Vybraná událost byla úspěšně připojena k této události jako podřízená událost messageEventLinkedToGroup = Vybraná událost byla úspěšně propojena s touto skupinou událostí +messageEventsLinkedToGroup = Vybrané událostí byly úspěšně propojeny s touto skupinou událostí +messageSomeEventsLinkedToGroup = Některé z vybraných událostí byly úspěšně propojeny s touto skupinou událostí messageEventOutsideJurisdictionDeletionDenied = Událost mimo jurisdikci uživatele nelze odstranit messageEventSuperordinateEventUnlinked = Spojení mezi touto událostí a její superordinate událostí bylo úspěšně odstraněno messageEventSubordinateEventUnlinked = Spojení mezi touto událostí a její podřízenou událostí bylo úspěšně odstraněno @@ -1146,12 +1146,14 @@ messageCountTravelEntriesNotRestored = %s travel entries not restored. UUIDs of messageCountVisitsNotDeleted = %s visits not deleted. UUIDs of visits not deleted\: %s messageCountEventsNotDeleted = %s events not deleted. UUIDs of events not deleted\: %s messageEventsNotDeletedExternalReason = The events mentioned in the above list of UUIDs could not be deleted because the communication with the reporting tool failed. -messageEventsNotDeletedLinkedEntitiesReason = No events that contain event participants linked will be deleted. Please remove the event participants from the event in order to be able to delete it. +messageEventsNotDeletedLinkedEntitiesReason = Žádné události, které obsahují propojené účastníky událostí, nebudou smazány. Odstraňte účastníky události z události, abyste ji mohli odstranit. messageExportFailed = Došlo k chybě bránící exportu dat. Kontaktujte prosím administrátora a informujte ho o tomto problému. messageExportConfigurationDeleted = Nastavení exportu odstraněno messageExportConfigurationSaved = Nastavení exportu uloženo messageFollowUpCanceled = Sledování všech vybraných kontaktů bylo zrušeno +messageFollowUpCanceledForSome = Sledování některých vybraných kontaktů bylo zrušeno messageFollowUpStatusChanged = Následná kontrola všech vybraných kontaktů, které byly ztraceny k následování +messageFollowUpStatusChangedForSome = Následná kontrola některých vybraných kontaktů, které byly následně ztraceny messageFacilityChanged = Změnili jste zařízení tohoto případu. Chcete přesunout případ do nového zařízení (hospitalizace může být aktualizována), nebo chcete pouze upravit data k nápravě chyby? messageFacilityMulitChanged = Změnili jste zařízení více případů. Chcete přenést tyto případy do nového zařízení (hospitalizace může být aktualizována), nebo chcete pouze upravit jejich data pro opravu chyb? messageGdpr = V souladu se zásadou minimalizace údajů uloženou GDPR, musíte zajistit, že zde zadáte pouze objektivní údaje, které jsou naprosto nezbytné pro zpracování souboru. Nesmíte zejména vkládat genetické nebo biometrické, filozofické, politické, náboženské údaje, odborářské názory, sexuální život nebo orientace, etnický původ, trestné činy, odsouzení, bezpečnostní opatření, trestní rejstřík . nebo jakékoli jiné údaje, které se netýkají veřejného zdravotního dohledu. @@ -1174,7 +1176,7 @@ messageImportSuccessful = Import úspěšný\!
Všechny řádky byly messageUploadSuccessful = Nahrávání úspěšné\! Nyní můžete toto okno zavřít. messageIncompleteGpsCoordinates = GPS souřadnice jsou neúplné messageExternalMessagesAssigned = Přiřazená osoba byla změněna pro všechny vybrané zprávy -messageExternalMessagesNotDeleted = The external messages mentioned in the above list of UUIDs could not be deleted. +messageExternalMessagesNotDeleted = Externí zprávy uvedené ve výše uvedeném seznamu UUID nelze odstranit. messageLoginFailed = Zkontrolujte své uživatelské jméno a heslo a zkuste to znovu messageMissingCases = Vygenerujte prosím některé případy před vytvořením kontaktů messageMissingDateFilter = Vyplňte prosím obě pole filtrování data @@ -1186,11 +1188,11 @@ messageNoContactsSelected = Nevybrali jste žádné kontakty messageNoCsvFile = Nevybrali jste soubor, který chcete nahrát. Vyberte prosím soubor .csv obsahující data, která chcete importovat z vašeho počítače. messageNoDocumentTemplateUploadFile = Nevybrali jste soubor, který chcete nahrát. Vyberte prosím šablonu .docx, kterou chcete importovat z vašeho počítače. messageNoDocumentUploadFile = Nevybrali jste soubor, který chcete nahrát. Vyberte soubor, který chcete importovat z vašeho počítače. -messageNoEligibleEventForDeletionSelected = None of the selected events are eligible for deletion -messageNoEnvironmentsSelected = You have not selected any environments +messageNoEligibleEventForDeletionSelected = Žádná z vybraných událostí není způsobilá pro smazání +messageNoEnvironmentsSelected = Nevybrali jste žádné prostředí messageNoEventParticipantsSelected = Nevybrali jste žádné účastníky události messageNoEventsSelected = Nevybrali jste žádné události -messageNoImmunizationsSelected = You have not selected any immunizations +messageNoImmunizationsSelected = Nevybrali jste žádné imunizace messageNoTravelEntriesSelected = Nevybrali jste žádná místa vstupu messageNoPathogenTestsSelected = Nevybrali jste žádné testy patogenu messageNoPrescriptionsSelected = Nevybrali jste žádné předpisy @@ -1219,8 +1221,8 @@ messageRelatedSampleFound = Vzorek zmíněný v této laboratoři již existuje. messageRelatedSampleAndLabMessagesFound = Zpráva laboratoře se stejným ID zprávy již byla zpracována. Souvisí se vzorkem odkazovaným v této laboratoři.
Chcete tento vzorek otevřít přímo? messageSampleErrors = Ve formuláři vzorku jsou chyby, opravte je a uložte vzorek, než jej předáte jiné laboratoři. messageSampleSaved = Data vzorku uložena -messageSamplesNotDeleted = The samples mentioned in the above list of UUIDs could not be deleted. -messageSamplesDeleted = All selected eligible samples have been deleted +messageSamplesNotDeleted = Vzorky uvedené ve výše uvedeném seznamu UUID nelze odstranit. +messageSamplesDeleted = Všechny vybrané způsobilé vzorky byly odstraněny messageSpecifyColumnAttribute = Zadejte atribut sloupce, který jste vybrali pro vizualizaci messageSpecifyFilterAttributes = Zadejte všechny vybrané atributy a podatributy filtru messageSpecifyRowAttribute = Zadejte atribut řádku, který jste vybrali pro vizualizaci @@ -1228,17 +1230,17 @@ messageSymptomsHint = Zaškrtněte prosím odpověď pro VŠECHNY příznaky, messageSymptomsVisitHint = Zaškrtněte prosím odpověď pro VŠECHNY příznaky, které naznačují, zda byly přítomny v době této návštěvy\: messageTaskArchived = Úkol byl archivován messageTasksEdited = Všechny úkoly byly upraveny -messageTasksNotDeleted = The tasks mentioned in the above list of UUIDs could not be deleted. +messageTasksNotDeleted = Úkoly uvedené ve výše uvedeném seznamu UUID nelze odstranit. messageTaskDearchived = Úkol byl dearchivován -messageTasksDeleted = All selected eligible tasks have been deleted +messageTasksDeleted = Všechny vybrané způsobilé úkoly byly odstraněny messageTemplateNotAvailable = Soubor šablony není k dispozici. Kontaktujte prosím administrátora a řekněte mu o tomto problému. messageTravelEntryOutsideJurisdictionDeletionDenied = Záznam o místě vstupu mimo jurisdikci uživatele nelze smazat messageTravelEntrySaved = Zadané údaje o cestování uloženy messageTravelEntryArchived = Místo vstupu bylo archivováno messageTravelEntryDearchived = Místo vstupu bylo vyjmuto z archivu messageTravelEntryPOEFilledBySystem = [System] Automaticky vyplněný vstupní bod -messageTravelEntriesNotDeleted = The travel entries mentioned in the above list of UUIDs could not be deleted. -messageTravelEntriesDeleted = All selected eligible travel entries have been deleted +messageTravelEntriesNotDeleted = Místa vstupu uvedené ve výše uvedeném seznamu UUID nelze odstranit. +messageTravelEntriesDeleted = Všechny vybrané záznamy o cestování byly odstraněny messageTreatmentCreated = Léčba vytvořena messageTreatmentSaved = Léčba uložena messageTreatmentsDeleted = Všechny vybrané léčby byly odstraněny @@ -1249,8 +1251,8 @@ messageDiseaseNotSpecifiedInLabMessage = Nemoc externí zprávy nebylo možné a messageUserRoleCombination = nelze kombinovat s messageUserRoleSaved = Uživatelská role uložena messageVaccinationOutsideJurisdictionDeletionDenied = Očkování mimo jurisdikci uživatele nelze odstranit -messageVisitsNotDeleted = The visits mentioned in the above list of UUIDs could not be deleted. -messageVisitsDeleted = All selected eligible visits have been deleted +messageVisitsNotDeleted = Návštěvy uvedené ve výše uvedeném seznamu UUID nelze odstranit. +messageVisitsDeleted = Všechny vybrané způsobilé návštěvy byly odstraněny messageWrongFileType = Zadejte soubor .csv obsahující data, která chcete importovat. Doporučuje se použít soubor importované šablony jako výchozí bod. messageWrongTemplateFileType=Pro %s poskytněte soubor.%s . messageLineListingDisabled = Výpis řádků byl zakázán @@ -1342,12 +1344,14 @@ messageUserSyncSuccessful = Synchronizace úspěšná\!
Všichni uži messageUserRightsExportFailed = Kontaktujte prosím administrátora a informujte ho o tomto problému messageNoExternalMessagesSelected = Nevybrali jste žádné zprávy messageExternalLabResultsAdapterNotFound = Adaptér výsledků externí laboratoře nebyl nalezen. To pravděpodobně znamená, že systém není správně nakonfigurován. Obraťte se na správce systému. -messageExternalMessagesEligibleForDeletion = Only unprocessed messages can be deleted -messageExternalMessagesDeleted = All selected eligible messages have been deleted +messageExternalMessagesEligibleForDeletion = Pouze nezpracované zprávy mohou být odstraněny +messageExternalMessagesDeleted = Všechny vybrané způsobilé zprávy byly odstraněny messageQuarantineOrderDocumentCreated = Doklad o příkazu karantény byl vytvořen messageUnavailableTaskEditionDueToDifferentDistricts = Editace úloh není k dispozici, pokud se týká různých okresů messageUsersEnabled = Všichni vybraní uživatelé byli povoleni +messageSomeUsersEnabled = Někteří z vybraných uživatelů byli povoleni messageUsersDisabled = Všichni vybraní uživatelé byli zakázáni +messageSomeUsersDisabled = Někteří z vybraných uživatelů byli zakázáni messageDontShareWithReportingToolWarning = Tento případ je aktivně blokován před zasíláním externím nástrojem pro hlášení zpráv messageBulkCasesWithDifferentDiseasesSelected = Vybrali jste případy s různými chorobami. Některé možnosti hromadné úpravy mohou být nedostupné. messageBulkContactsWithDifferentDiseasesSelected = Vybrali jste kontakty s různými chorobami. Některé možnosti hromadné úpravy mohou být nedostupné. @@ -1379,10 +1383,10 @@ messageUserRoleUnusableForLogin = Uživatelé s pouze touto rolí se nebudou moc messageUserRoleHasNoRights = Tato uživatelská role nemá žádná práva. Vyberte prosím alespoň jedno právo. messageEntriesEditedExceptArchived = %s položek bylo úspěšně upraveno. Některé položky nemohly být upraveny, protože jsou v jiné jurisdikci nebo již byly archivovány. messageEntriesEdited = Všechny položky byly upraveny -messageAllEntitiesArchived = All selected entries have been archived -messageSomeEntitiesArchived = %s entries have been archived. -messageAllEntitiesDearchived = All selected entries have been dearchived -messageSomeEntitiesDearchived = %s entries have been dearchived. +messageAllEntitiesArchived = Všechny vybrané položky byly archivovány +messageSomeEntitiesArchived = %s položek bylo archivováno. +messageAllEntitiesDearchived = Všechny vybrané položky byly dearchivovány +messageSomeEntitiesDearchived = %s záznamů bylo dearchivováno. messageEnvironmentCreated = Environment created messageEnvironmentSaved = Environment saved messageEnvironmentArchived = Environment has been archived @@ -1589,6 +1593,7 @@ infoBAGExport=Plný export do SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Záznam byl odeslán do nástroje hlášení ExternalSurveillanceToolGateway.notificationEntriesSent = Všechny vybrané položky byly odeslány do oznamovacího nástroje. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Některé z vybraných položek byly odeslány do oznamovacího nástroje. ExternalSurveillanceToolGateway.notificationEntriesDeleted = Všechny vybrané položky byly úspěšně odstraněny v nástroji hlášení. ExternalSurveillanceToolGateway.notificationEntryNotSent = Záznam nemohl být odeslán ExternalSurveillanceToolGateway.notificationErrorSending = Chyba při odesílání záznamu diff --git a/sormas-api/src/main/resources/strings_de-CH.properties b/sormas-api/src/main/resources/strings_de-CH.properties index c49b1a9314e..e4bfc370682 100644 --- a/sormas-api/src/main/resources/strings_de-CH.properties +++ b/sormas-api/src/main/resources/strings_de-CH.properties @@ -538,10 +538,8 @@ headingExportFailed = Export fehlgeschlagen headingFatalities=Todesfälle headingFileExists = Duplikatdatei headingFilters = Filter -headingFollowUpCanceled = Follow-up/Nachverfolgung abgebrochen headingStoppedFollowUp = Follow-up/Nachverfolgung gestoppt headingFollowUpStatus = Follow-up/Nachverfolgungs-Status -headingFollowUpStatusChanged = Follow-up/Nachverfolgungs-Status geändert headingHealthConditions = Vorerkrankungen headingHospitalization = Daten zum Krankenhausaufenthalt headingPreviousHospitalizations = Vorherige Krankenhausaufenthalte @@ -771,8 +769,6 @@ headingCaution = Achtung headingUnavailableTaskEdition = Unverfügbare Aufgabenbearbeitung headingDeleteVaccinations = Impfungen entfernen headingDocumentCreated = Dokument erstellt -headingUsersEnabled = Benutzer aktiviert -headingUsersDisabled = Benutzer deaktiviert headingConfirmUnclearLabMessage=Unklar bestätigen headingConfirmManuallyForwardedLabMessage=Weitergeleitet bestätigen headingUpdateCaseWithNewDiseaseVariant=Krankheitsvariante des Falls aktualisieren @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Impfung immunizationRecoveryHeading = Genesung headingAutomaticDeletionStarted = Automatisches Löschen gestartet headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Bitte dokumentieren Sie ALLE relevanten Aktivitäten nach der Infektion\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = Alle Fälle sind bereits mit dem ausgewählten E messageAllCasesLinkedToEvent = Alle Fälle wurden mit dem ausgewählten Ereignis verknüpft. messageAllContactsAlreadyInEvent = Alle Kontakte sind bereits mit dem ausgewählten Ereignis verknüpft. messageAllContactsLinkedToEvent = Alle Kontakte wurden mit dem ausgewählten Ereignis verknüpft. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = Die Person, die Sie ausgewählt haben, ist bereits als Ereignisteilnehmer dieser Veranstaltung definiert. messageAnimalContactsHint = Bitte geben Sie eine Antwort in Bezug auf ALLE Tiere (lebendig oder tot) an, denen die Person während der Inkubationszeit direkt ausgesetzt war (z.B. Jagd, Berühren, Essen). messageArchiveUndoneReasonMandatory = Bitte geben Sie einen Grund für die Dearchivierung an @@ -1106,6 +1104,8 @@ messageEventGroupCreated = Neue Ereignisgruppe erstellt messageEventLinkedAsSuperordinate = Das ausgewählte Ereignis wurde erfolgreich als übergeordnetes Ereignis mit diesem Ereignis verknüpft messageEventLinkedAsSubordinate = Das ausgewählte Ereignis wurde erfolgreich als untergeordnetes Ereignis mit diesem Ereignis verknüpft messageEventLinkedToGroup = Das ausgewählte Ereignis wurde erfolgreich mit dieser Ereignisgruppe verknüpft +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = Die Verbindung zwischen diesem Ereignis und seinem übergeordneten Ereignis wurde erfolgreich entfernt messageEventSubordinateEventUnlinked = Die Verbindung zwischen diesem Ereignis und seinem untergeordneten Ereignis wurde erfolgreich entfernt @@ -1151,7 +1151,9 @@ messageExportFailed = Es gab einen Fehler beim Export der Daten. Bitte kontaktie messageExportConfigurationDeleted = Exporteinstellung gelöscht messageExportConfigurationSaved = Exporteinstellung gespeichert messageFollowUpCanceled = Die Nachverfolgung aller ausgewählten Kontakte wurde abgebrochen +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Das Follow-up/die Nachverfolgung aller ausgewählten Kontakte mit Follow-up/Nachverfolgung wurde auf "Nachverfolgung nicht möglich" gesetzt +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = Sie haben die Einrichtung dieses Falls geändert. Möchten Sie den Fall an die neue Einrichtung übertragen (der Krankenhausaufenthalt würde möglicherweise aktualisiert werden) oder nur die Daten bearbeiten, um einen Fehler zu korrigieren? messageFacilityMulitChanged = Sie haben die Einrichtung mehrerer Fälle geändert. Möchten Sie diese Fälle an die neue Einrichtung übertragen (der Krankenhausaufenthalt würde möglicherweise aktualisiert werden) oder nur die Daten bearbeiten, um einen Fehler zu korrigieren? messageGdpr = Gemäss dem von der DSGVO/GDPR vorgeschriebenen Prinzip der Datenminimierung müssen Sie sicherstellen, dass Sie hier nur objektive Daten eingeben, die für die Verarbeitung der Datei absolut notwendig sind. Insbesondere dürfen Sie weder genetische noch biometrische Daten eingeben, noch philosophische, politische, religiöse und gewerkschaftliche Meinungen, sexuelles Leben oder Orientierung, ethnische Herkunft, Straftaten, Verurteilungen, Sicherheitsmassnahmen ... oder andere Daten, die nicht mit der Gesundheitsbefragung zusammenhängen. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Dokument wurde erstellt messageUnavailableTaskEditionDueToDifferentDistricts = Die Aufgabenbearbeitung ist nicht verfügbar, wenn sie mit verschiedenen Bezirken verknüpft sind messageUsersEnabled = Alle ausgewählten Benutzer wurden aktiviert +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = Alle ausgewählten Benutzer wurden deaktiviert +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = Dieser Fall wird aktiv daran gehindert, an die Meldesoftware gesendet zu werden messageBulkCasesWithDifferentDiseasesSelected = Sie haben Fälle mit unterschiedlichen Krankheiten ausgewählt. Einige Massenbearbeitungsoptionen sind möglicherweise nicht verfügbar. messageBulkContactsWithDifferentDiseasesSelected = Sie haben Kontakte mit verschiedenen Krankheiten ausgewählt. Einige Massenbearbeitungsoptionen sind möglicherweise nicht verfügbar. @@ -1589,6 +1593,7 @@ infoBAGExport=Vollständiger Export zu SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Eintrag wurde an die Meldesoftware gesendet ExternalSurveillanceToolGateway.notificationEntriesSent = Alle ausgewählten Einträge wurden an die Meldesoftware gesendet. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = Alle ausgewählten Einträge wurden erfolgreich in der Meldesoftware gelöscht. ExternalSurveillanceToolGateway.notificationEntryNotSent = Eintrag konnte nicht gesendet werden ExternalSurveillanceToolGateway.notificationErrorSending = Fehler beim Senden des Eintrags diff --git a/sormas-api/src/main/resources/strings_de-DE.properties b/sormas-api/src/main/resources/strings_de-DE.properties index 479ce82a6fb..09e13e15970 100644 --- a/sormas-api/src/main/resources/strings_de-DE.properties +++ b/sormas-api/src/main/resources/strings_de-DE.properties @@ -538,10 +538,8 @@ headingExportFailed = Export fehlgeschlagen headingFatalities=Todesfälle headingFileExists = Duplikatdatei headingFilters = Filter -headingFollowUpCanceled = Nachverfolgung abgebrochen headingStoppedFollowUp = Nachverfolgung gestoppt headingFollowUpStatus = Nachverfolgungs-Status -headingFollowUpStatusChanged = Nachverfolgungs-Status geändert headingHealthConditions = Vorerkrankungen headingHospitalization = Aktueller Krankenhausaufenthalt headingPreviousHospitalizations = Vorherige Krankenhausaufenthalte @@ -771,8 +769,6 @@ headingCaution = Achtung headingUnavailableTaskEdition = Unverfügbare Aufgabenbearbeitung headingDeleteVaccinations = Impfungen entfernen headingDocumentCreated = Dokument erstellt -headingUsersEnabled = Benutzer aktiviert -headingUsersDisabled = Benutzer deaktiviert headingConfirmUnclearLabMessage=Unklar bestätigen headingConfirmManuallyForwardedLabMessage=Weitergeleitet bestätigen headingUpdateCaseWithNewDiseaseVariant=Krankheitsvariante des Falls aktualisieren @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Impfung immunizationRecoveryHeading = Genesung headingAutomaticDeletionStarted = Automatisches Löschen gestartet headingBulkOperationProgress = Fortschritt bei der Massenverarbeitung +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Bitte dokumentieren Sie ALLE relevanten Betreuungen, Unterbringungen und Tätigkeiten in Einrichtungen\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = Alle Fälle sind bereits mit dem ausgewählten E messageAllCasesLinkedToEvent = Alle Fälle wurden mit dem ausgewählten Ereignis verknüpft. messageAllContactsAlreadyInEvent = Alle Kontakte sind bereits mit dem ausgewählten Ereignis verknüpft. messageAllContactsLinkedToEvent = Alle Kontakte wurden mit dem ausgewählten Ereignis verknüpft. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = Die Person, die Sie ausgewählt haben, ist bereits als Ereignisteilnehmer dieser Veranstaltung definiert. messageAnimalContactsHint = Bitte geben Sie eine Antwort in Bezug auf ALLE Tiere (lebendig oder tot) an, denen die Person während der Inkubationszeit direkt ausgesetzt war (z.B. Jagd, Berühren, Essen). messageArchiveUndoneReasonMandatory = Bitte geben Sie einen Grund für die Wiedereröffnung an @@ -1106,6 +1104,8 @@ messageEventGroupCreated = Neue Ereignisgruppe erstellt messageEventLinkedAsSuperordinate = Das ausgewählte Ereignis wurde erfolgreich als übergeordnetes Ereignis mit diesem Ereignis verknüpft messageEventLinkedAsSubordinate = Das ausgewählte Ereignis wurde erfolgreich als untergeordnetes Ereignis mit diesem Ereignis verknüpft messageEventLinkedToGroup = Das ausgewählte Ereignis wurde erfolgreich mit dieser Ereignisgruppe verknüpft +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = Das Ereignis außerhalb der Zuständigkeit des Benutzers kann nicht gelöscht werden messageEventSuperordinateEventUnlinked = Die Verbindung zwischen diesem Ereignis und seinem übergeordneten Ereignis wurde erfolgreich entfernt messageEventSubordinateEventUnlinked = Die Verbindung zwischen diesem Ereignis und seinem untergeordneten Ereignis wurde erfolgreich entfernt @@ -1151,7 +1151,9 @@ messageExportFailed = Es gab einen Fehler beim Export der Daten. Bitte kontaktie messageExportConfigurationDeleted = Exporteinstellung gelöscht messageExportConfigurationSaved = Exporteinstellung gespeichert messageFollowUpCanceled = Die Nachverfolgung aller ausgewählten Kontakte wurde abgebrochen +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Die Nachverfolgung aller ausgewählten Kontakte mit Nachverfolgung wurde auf "Nachverfolgung nicht möglich" gesetzt +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = Sie haben die Einrichtung dieses Falls geändert. Möchten Sie den Fall an die neue Einrichtung übertragen (der Krankenhausaufenthalt wird aktualisiert) oder nur die Daten bearbeiten, um einen Fehler zu korrigieren? messageFacilityMulitChanged = Sie haben die Einrichtung mehrerer Fälle geändert. Möchten Sie den Fall an die neue Einrichtung übertragen (der Krankenhausaufenthalt wird möglicherweise aktualisiert) oder nur die Daten bearbeiten, um einen Fehler zu korrigieren? messageGdpr = Gemäß dem von der DSGVO vorgeschriebenen Prinzip der Datenminimierung müssen Sie sicherstellen, dass Sie hier nur objektive Daten eingeben, die für die Verarbeitung der Daten absolut notwendig sind. Insbesondere dürfen Sie weder biometrische, philosophische, politische oder religiöse Daten, noch gewerkschaftliche Meinungen, sexuelles Leben oder Orientierung, ethnische Herkunft, Straftaten, Verurteilungen, Sicherheitsmaßnahmen, Vorbestrafungen ... oder andere Daten, die nicht mit der Gesundheitsbefragung zusammenhängen eingeben. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Dokument wurde erstellt messageUnavailableTaskEditionDueToDifferentDistricts = Die Aufgabenbearbeitung ist nicht verfügbar, wenn sie mit verschiedenen Landkreisen verknüpft sind messageUsersEnabled = Alle ausgewählten Benutzer wurden aktiviert +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = Alle ausgewählten Benutzer wurden deaktiviert +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = Dieser Fall wird aktiv daran gehindert, an die Meldesoftware gesendet zu werden messageBulkCasesWithDifferentDiseasesSelected = Sie haben Fälle mit unterschiedlichen Krankheiten ausgewählt. Einige Massenbearbeitungsoptionen sind möglicherweise nicht verfügbar. messageBulkContactsWithDifferentDiseasesSelected = Sie haben Kontakte mit verschiedenen Krankheiten ausgewählt. Einige Massenbearbeitungsoptionen sind möglicherweise nicht verfügbar. @@ -1589,6 +1593,7 @@ infoBAGExport=Kompletter Export zu SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Eintrag wurde an die Meldesoftware gesendet ExternalSurveillanceToolGateway.notificationEntriesSent = Alle ausgewählten Einträge wurden an die Meldesoftware gesendet. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = Alle ausgewählten Einträge wurden erfolgreich in der Meldesoftware gelöscht. ExternalSurveillanceToolGateway.notificationEntryNotSent = Eintrag konnte nicht gesendet werden ExternalSurveillanceToolGateway.notificationErrorSending = Fehler beim Senden des Eintrags diff --git a/sormas-api/src/main/resources/strings_en-AF.properties b/sormas-api/src/main/resources/strings_en-AF.properties index 6a2c0780683..3fae4104f22 100644 --- a/sormas-api/src/main/resources/strings_en-AF.properties +++ b/sormas-api/src/main/resources/strings_en-AF.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_en-GH.properties b/sormas-api/src/main/resources/strings_en-GH.properties index b4caebe345f..19f7c2923cc 100644 --- a/sormas-api/src/main/resources/strings_en-GH.properties +++ b/sormas-api/src/main/resources/strings_en-GH.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_en-NG.properties b/sormas-api/src/main/resources/strings_en-NG.properties index 196ba0108bc..41760dff668 100644 --- a/sormas-api/src/main/resources/strings_en-NG.properties +++ b/sormas-api/src/main/resources/strings_en-NG.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_es-CU.properties b/sormas-api/src/main/resources/strings_es-CU.properties index 51b854ba24d..a3d3b5b74e4 100644 --- a/sormas-api/src/main/resources/strings_es-CU.properties +++ b/sormas-api/src/main/resources/strings_es-CU.properties @@ -538,10 +538,8 @@ headingExportFailed = Falló la exportación headingFatalities=Muertes headingFileExists = Archivo duplicado headingFilters = Filtros -headingFollowUpCanceled = Seguimiento cancelado headingStoppedFollowUp = Seguimiento detenido headingFollowUpStatus = Estado de seguimiento -headingFollowUpStatusChanged = Se modificó el estado de seguimiento headingHealthConditions = Condiciones preexistentes headingHospitalization = Datos de hospitalización headingPreviousHospitalizations = Hospitalizaciones anteriores @@ -771,8 +769,6 @@ headingCaution = Alerta headingUnavailableTaskEdition = Edición de tareas no disponible headingDeleteVaccinations = Eliminar vacunaciones de inmunización headingDocumentCreated = Documento creado -headingUsersEnabled = Usuarios activados -headingUsersDisabled = Usuarios desactivados headingConfirmUnclearLabMessage=Confirmar poco claro headingConfirmManuallyForwardedLabMessage=Confirmar reenviado headingUpdateCaseWithNewDiseaseVariant=Actualizar variante de enfermedad de caso @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vacunación immunizationRecoveryHeading = Recuperación headingAutomaticDeletionStarted = Eliminación automática iniciada headingBulkOperationProgress = Progreso de la operación masiva +headingSomeContactsAlreadyInEvent = Algunos contactos ya están vinculados al evento seleccionado # Info texts infoActivityAsCaseInvestigation = Por favor, documente TODAS las actividades relevantes después de la infección\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = Todos los casos ya están vinculados al evento s messageAllCasesLinkedToEvent = Todos los casos fueron vinculados al evento seleccionado. messageAllContactsAlreadyInEvent = Todos los contactos ya están vinculados al evento seleccionado. messageAllContactsLinkedToEvent = Todos los contactos fueron vinculados al evento seleccionado. +messageSomeContactsLinkedToEvent = Algunos de los contactos seleccionados fueron vinculados al evento seleccionado. messageAlreadyEventParticipant = La persona seleccionada ya está definida como participante de este evento. messageAnimalContactsHint = Por favor, indique una respuesta con respecto a TODOS los animales (vivos o muertos) a los que la persona se expuso directamente (por ejemplo, cazó, tocó, comió) durante el período de incubación. messageArchiveUndoneReasonMandatory = Por favor, agregue una razón para desarchivar @@ -1106,6 +1104,8 @@ messageEventGroupCreated = Nuevo grupo de eventos creado messageEventLinkedAsSuperordinate = El evento seleccionado fue vinculado exitosamente a este evento como su evento superior messageEventLinkedAsSubordinate = El evento seleccionado fue vinculado exitosamente a este evento como un evento subordinado messageEventLinkedToGroup = El evento seleccionado fue vinculado exitosamente a este grupo de eventos +messageEventsLinkedToGroup = Los eventos seleccionados fueron vinculados exitosamente a este grupo de eventos +messageSomeEventsLinkedToGroup = Algunos de los eventos seleccionados fueron vinculados exitosamente a este grupo de eventos messageEventOutsideJurisdictionDeletionDenied = El evento fuera de la jurisdicción del usuario no puede ser eliminado messageEventSuperordinateEventUnlinked = El vínculo entre este evento y su evento superior fue eliminado exitosamente messageEventSubordinateEventUnlinked = El vínculo entre este evento y su evento subordinado fue eliminado exitosamente @@ -1151,7 +1151,9 @@ messageExportFailed = Un error impidió exportar los datos. Por favor, contacte messageExportConfigurationDeleted = Configuración de exportación eliminada messageExportConfigurationSaved = Configuración de exportación guardada messageFollowUpCanceled = El seguimiento de todos los contactos seleccionados fue cancelado +messageFollowUpCanceledForSome = El seguimiento de algunos contactos seleccionados fue cancelado messageFollowUpStatusChanged = El seguimiento de todos los contactos seleccionados que tienen seguimiento se especificó como seguimiento perdido +messageFollowUpStatusChangedForSome = El seguimiento de algunos contactos seleccionados que tienen seguimiento se especificó como seguimiento perdido messageFacilityChanged = Ha cambiado la instalación de este caso. ¿Desea transferir el caso a la nueva instalación (la hospitalización puede ser actualizada) o sólo desea editar los datos para corregir un error? messageFacilityMulitChanged = Ha cambiado la instalación de múltiples casos. ¿Desea transferir estos casos a la nueva instalación (la hospitalización puede actualizada) o sólo desea editar sus datos para corregir errores? messageGdpr = Debe asegurarse de introducir aquí sólo datos objetivos absolutamente necesarios para el procesamiento del archivo. En particular, no debe introducir datos genéticos o biométricos, filosóficos, políticos, religiosos, opiniones sindicales, vida u orientación sexual, origen étnico, delitos, condenas, medidas de seguridad, antecedentes penales ... o cualquier otro dato que no esté relacionado con la vigilancia de la salud pública. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = Todos los mensajes elegibles seleccionados fuer messageQuarantineOrderDocumentCreated = El documento para orden de cuarentena fue creado messageUnavailableTaskEditionDueToDifferentDistricts = La edición de tareas no está disponible si están relacionadas con diferentes municipios messageUsersEnabled = Todos los usuarios seleccionados fueron activados +messageSomeUsersEnabled = Algunos de los usuarios seleccionados fueron activados messageUsersDisabled = Todos los usuarios seleccionados fueron desactivados +messageSomeUsersDisabled = Algunos de los usuarios seleccionados fueron desactivados messageDontShareWithReportingToolWarning = Se evita activamente el envío de este caso a la herramienta externa de reporte messageBulkCasesWithDifferentDiseasesSelected = Ha seleccionado casos con diferentes enfermedades. Algunas opciones de edición masiva podrían no estar disponibles. messageBulkContactsWithDifferentDiseasesSelected = Ha seleccionado contactos con diferentes enfermedades. Algunas opciones de edición masiva podrían no estar disponibles. @@ -1589,6 +1593,7 @@ infoBAGExport=Exportar completamente a SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entrada enviada a la herramienta de reporte ExternalSurveillanceToolGateway.notificationEntriesSent = Todas las entradas seleccionadas se enviaron a la herramienta de informes. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Algunas de las entradas seleccionadas se enviaron a la herramienta de informes. ExternalSurveillanceToolGateway.notificationEntriesDeleted = Todas las entradas seleccionadas fueron eliminadas exitosamente en la herramienta de reporte. ExternalSurveillanceToolGateway.notificationEntryNotSent = La entrada no se pudo enviar ExternalSurveillanceToolGateway.notificationErrorSending = Error al enviar la entrada diff --git a/sormas-api/src/main/resources/strings_es-ES.properties b/sormas-api/src/main/resources/strings_es-ES.properties index 9b4de2be5d9..89f7838d10f 100644 --- a/sormas-api/src/main/resources/strings_es-ES.properties +++ b/sormas-api/src/main/resources/strings_es-ES.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_fa-AF.properties b/sormas-api/src/main/resources/strings_fa-AF.properties index 9b4de2be5d9..89f7838d10f 100644 --- a/sormas-api/src/main/resources/strings_fa-AF.properties +++ b/sormas-api/src/main/resources/strings_fa-AF.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_fi-FI.properties b/sormas-api/src/main/resources/strings_fi-FI.properties index 518742a75ba..38515aad5e3 100644 --- a/sormas-api/src/main/resources/strings_fi-FI.properties +++ b/sormas-api/src/main/resources/strings_fi-FI.properties @@ -538,10 +538,8 @@ headingExportFailed = Vienti epäonnistui headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Suodattimet -headingFollowUpCanceled = Seuranta peruttu headingStoppedFollowUp = Seuranta päättynyt headingFollowUpStatus = Seurannan tila -headingFollowUpStatusChanged = Seurannan tila vaihdettu headingHealthConditions = Perussairaudet headingHospitalization = Sairaalahoidon tiedot headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Merkitse vastaus koskien KAIKKIA eläimiä (eläviä tai kuolleita), joille henkilö on suoraan altistunut (esim. metsästäessä, koskettaessa, syömällä) itämisajan aikana. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = Kohdattiin ongelma, jonka takia tietoja ei saatu vietyä. messageExportConfigurationDeleted = Vientiasetukset poistettu messageExportConfigurationSaved = Vientiasetukset tallennettu messageFollowUpCanceled = Kaikkien valittujen kontaktien seuranta on peruttu +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Kaikkien niiden valittujen kontaktien osalta, jolla on seuranta-aikaa, on seurannan tila asetettu seurannasta kadonneeksi +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_fil-PH.properties b/sormas-api/src/main/resources/strings_fil-PH.properties index 9b4de2be5d9..89f7838d10f 100644 --- a/sormas-api/src/main/resources/strings_fil-PH.properties +++ b/sormas-api/src/main/resources/strings_fil-PH.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_fj-FJ.properties b/sormas-api/src/main/resources/strings_fj-FJ.properties index 9b4de2be5d9..89f7838d10f 100644 --- a/sormas-api/src/main/resources/strings_fj-FJ.properties +++ b/sormas-api/src/main/resources/strings_fj-FJ.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_fr-CD.properties b/sormas-api/src/main/resources/strings_fr-CD.properties index 8c7c92b36d8..e0bd5dd3094 100644 --- a/sormas-api/src/main/resources/strings_fr-CD.properties +++ b/sormas-api/src/main/resources/strings_fr-CD.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Current Hospitalization headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_fr-CH.properties b/sormas-api/src/main/resources/strings_fr-CH.properties index 3ae6e0f70a1..3ef3cd80e9e 100644 --- a/sormas-api/src/main/resources/strings_fr-CH.properties +++ b/sormas-api/src/main/resources/strings_fr-CH.properties @@ -538,10 +538,8 @@ headingExportFailed = Exportation échouée headingFatalities=Fatalities headingFileExists = Dupliquer le fichier headingFilters = Filtres -headingFollowUpCanceled = Suivi annulé headingStoppedFollowUp = Suivi arrêté headingFollowUpStatus = Statut de suivi -headingFollowUpStatusChanged = Statut de suivi modifié headingHealthConditions = Other health conditions headingHospitalization = Données d'hospitalisation headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = La personne sélectionnée est déjà un participant à cet événement. messageAnimalContactsHint = Veuillez indiquer une réponse concernant TOUS les animaux (vivants ou morts) que la personne a eu une exposition directe (par exemple chasse, toucher, manger) pendant la période d'incubation. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = Il y a eu une erreur empêchant l'exportation des données messageExportConfigurationDeleted = Configuration d'export supprimée messageExportConfigurationSaved = Configuration d'exportation enregistrée messageFollowUpCanceled = Le suivi de tous les contacts sélectionnés a été annulé +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Le suivi de tous les contacts sélectionnés qui n'ont pas terminé leur suivi a été paramétré pour être perdu de vue +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = Vous avez changé le centre de santé de ce cas. Souhaitez-vous transférer le cas dans le nouvel établissement de santé (l'hospitalisation serait mise à jour) ou souhaitez-vous modifier les données seulement pour corriger une erreur? messageFacilityMulitChanged = Vous avez changé l'établissement de santé de plusieurs cas. Souhaitez-vous transférer ces cas vers le nouvel établissement de santé (l'hospitalisation serait mise à jour) ou souhaitez-vous modifier les données seulement pour corriger des erreurs? messageGdpr = Conformément au principe de minimisation des données imposé par le RGPD, vous devez veiller à ne saisir ici que des données objectives absolument nécessaires au traitement du dossier. En particulier, vous ne devez pas saisir de données génétiques ou biométriques, opinions philosophiques, politiques, religieuses, syndicales, vie sexuelle ou orientation, origine ethnique, infractions, condamnations, mesures de sûreté, casier judiciaire… ou toutes autres données qui ne seraient pas en rapport avec l’enquête sanitaire. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Exportation complète vers SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_fr-FR.properties b/sormas-api/src/main/resources/strings_fr-FR.properties index 584361093f7..1fd68003500 100644 --- a/sormas-api/src/main/resources/strings_fr-FR.properties +++ b/sormas-api/src/main/resources/strings_fr-FR.properties @@ -152,7 +152,7 @@ confirmationDearchiveEventParticipant = Êtes-vous sûr de vouloir désarchiver confirmationDearchiveEventGroup = Êtes-vous sûr de vouloir désarchiver ce groupe d'événements? Cela le fera apparaître dans le répertoire normal des groupes d'événements. confirmationDeleteCases = Êtes-vous sûr de vouloir supprimer tous les %d cas sélectionnés ?

Si elles sont référencées par d'autres données dans le système, ces références seront supprimées, ce qui ne peut pas être annulé automatiquement. confirmationDeleteContacts = Voulez-vous vraiment supprimer tous les %d contacts sélectionnés ?

Si elles sont référencées par d'autres données dans le système, ces références seront supprimées, ce qui ne peut pas être annulé automatiquement. -confirmationDeleteEntities = Are you sure you want to delete all %d selected %s?

If referenced by other data in the system, those references will be removed, which cannot be automatically undone. +confirmationDeleteEntities = Êtes-vous sûr de vouloir supprimer toute la %d sélection %s?

S'il existe des liens vers d'autres données dans le système, ces liens seront supprimés, ce qui ne peut pas être annulé automatiquement. confirmationRestoreEntities = Êtes-vous sûr de vouloir restaurer tous les %d sélectionnés %s? confirmationDeleteEntity = Êtes-vous sûr de vouloir supprimer ce %s ?

Si référencé par d'autres données dans le système, ces références seront supprimées, ceci qui ne peut pas être annulé automatiquement. confirmationDeleteEntityWithDetails = Êtes-vous sûr de vouloir supprimer ce %s ?

Si référencé par d'autres données dans le système, ces références seront supprimées, ce qui ne peut pas être annulé automatiquement. @@ -299,7 +299,7 @@ entityTreatments = Traitements entityUser = Utilisateur entityUsers = Utilisateurs entityExposure = Exposition -entityExternalMessages = External messages +entityExternalMessages = Messages externes entityCampaignData = Données de la campagne entityCampaignDataForm=formulaire de données de campagne entityStatistics = Statistiques @@ -538,10 +538,8 @@ headingExportFailed = Exportation échouée headingFatalities=Fatalité headingFileExists = Dupliquer le fichier headingFilters = Filtres -headingFollowUpCanceled = Suivi annulé headingStoppedFollowUp = Suivi arrêté headingFollowUpStatus = Statut de suivi -headingFollowUpStatusChanged = Statut de suivi modifié headingHealthConditions = Antécédents médicaux headingHospitalization = Données d'hospitalisation headingPreviousHospitalizations = Hospitalisations précédentes @@ -715,20 +713,20 @@ headingNoEventFound = Aucun événement trouvé headingEventNotDeleted = Événement non supprimé headingSomeCasesNotDeleted = Certains cas n'ont pas été supprimés headingSomeCasesNotRestored = Certains cas n'ont pas été restaurés -headingSomeContactsNotDeleted = Some contacts were not deleted +headingSomeContactsNotDeleted = Certains contacts n'ont pas été supprimés headingSomeContactsNotRestored = Certains cas n'ont pas été restaurés headingSomeEventsNotRestored = Certains événements n'ont pas été restaurés -headingSomeEventParticipantsNotDeleted = Some event participants were not deleted +headingSomeEventParticipantsNotDeleted = Certains participants à l'événement n'ont pas été supprimés headingSomeEventParticipantsNotRestored = Certains participants à l'événement n'ont pas été restaurés headingSomeImmunizationsNotRestored = Certaines immunisations n'ont pas été restaurées -headingSomeSamplesNotDeleted = Some samples were not deleted +headingSomeSamplesNotDeleted = Certains échantillons n'ont pas été supprimés headingSomeSamplesNotRestored = Certains échantillons n'ont pas été restaurés -headingSomeTasksNotDeleted = Some tasks were not deleted -headingSomeTravelEntriesNotDeleted = Some travel entries were not deleted +headingSomeTasksNotDeleted = Certaines tâches n'ont pas été supprimées +headingSomeTravelEntriesNotDeleted = Certaines entrées de voyage n'ont pas été supprimées headingSomeTravelEntriesNotRestored = Certaines entrées de voyage n'ont pas été restaurés -headingSomeVisitsNotDeleted = Some visits were not deleted +headingSomeVisitsNotDeleted = Certaines visites n'ont pas été supprimées headingSomeEventsNotDeleted = Certains événements n'ont pas été supprimés -headingSomeExternalMessagesNotDeleted = Some external messages were not deleted +headingSomeExternalMessagesNotDeleted = Certains messages externes n'ont pas été supprimés headingContactConfirmationRequired = Confirmation du contact requise headingContactConversionFollowUpCommentLarge = Le commentaire de suivi dépasse le nombre maximum de caractères autorisés headingSelectSourceCase = Sélectionner le cas source @@ -771,8 +769,6 @@ headingCaution = Attention headingUnavailableTaskEdition = Édition de la tâche indisponible headingDeleteVaccinations = Enlever l'immunité par vaccination headingDocumentCreated = Document créé -headingUsersEnabled = Utilisateurs activés -headingUsersDisabled = Utilisateurs désactivés headingConfirmUnclearLabMessage=Confirmer la suppression headingConfirmManuallyForwardedLabMessage=Confirmation transmise headingUpdateCaseWithNewDiseaseVariant=Mettre à jour la variante de la maladie du cas @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Récupération headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Veuillez documenter toutes les activités pertinentes après l'infection \: @@ -999,10 +996,10 @@ infoNoAccessToPersonEntities = You don't have the necessary user rights to view infoDashboardFinalLaboratoryResult = When a case has multiple samples, only the final laboratory result of the sample with the latest sample collection date is considered. infoBulkProcess = %d selected entries are currently being processed. This may take a while. The progress will be updated for each 20 entries that have been processed. infoBulkProcessFinished = All selected entries have been processed\!
You can now close this window. -infoBulkProcessFinishedWithIneligibleItems = Bulk process has been successfully completed\!
However, some of the selected entries could not be processed, because they were not eligible. -infoBulkProcessFinishedWithSkipsOutsideJurisdiction = Bulk process has been successfully completed\!
However, some of the selected entries could not be processed, most likely because they were outside your jurisdiction. -infoBulkProcessFinishedWithSkips = Bulk process has been successfully completed\!
However, some of the selected entries could not be processed, most likely because they were outside your jurisdiction, already archived or not eligible. -infoBulkProcessNoEligibleEntries = Bulk process has been cancelled because there are no eligible entries for this operation\! +infoBulkProcessFinishedWithIneligibleItems = Le processus en lot a été complété avec succès \!
Cependant, certaines des entrées sélectionnées n'ont pas pu être traitées, car elles n'étaient pas éligibles. +infoBulkProcessFinishedWithSkipsOutsideJurisdiction = Le processus en lot a été complété avec succès \!
Cependant, certaines des entrées sélectionnées n'ont pas pu être traitées, probablement parce qu'elles étaient hors de votre juridiction. +infoBulkProcessFinishedWithSkips = Le traitement en lot a été complété avec succès \!
Cependant, certaines des entrées sélectionnées n'ont pas pu être traitées, probablement parce qu'ils étaient hors de votre juridiction, déjà archivés ou non admissibles. +infoBulkProcessNoEligibleEntries = Le processus en lot a été annulé car il n'y a pas d'entrées éligibles pour cette opération \! infoBulkProcessCancelled = Bulk process has been cancelled\!
All selected entries up until this point have been processed. You can now close this window. All not yet processed entries will still be selected. infoBulkUnresponsiveWindowHint = Hint\: If the progress bar seems to be unresponsive and no progress is visible after a while, try to click this popup window or resize your browser window. @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = Tous les contacts ont été liés à l'événement sélectionné. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = La personne que vous avez sélectionnée est déjà définie comme participant à cet événement. messageAnimalContactsHint = Veuillez indiquer une réponse concernant TOUS les animaux (vivants ou morts) que la personne a eu une exposition directe (par exemple chasse, toucher, manger) pendant la période d'incubation. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1039,7 +1037,7 @@ messageCaseRelationToEventWithoutDisease=Il n'est pas possible de lier un cas à messageCaseSaved = Cas enregistré messageCaseSavedClassificationChanged = Cas enregistré. La classification a été automatiquement modifiée en %s. messageCaseTransfered = Le cas a été transféré à un autre établissement de santé -messageCasesNotDeleted = The cases mentioned in the above list of UUIDs could not be deleted. +messageCasesNotDeleted = Les cas mentionnés dans la liste des UUID ci-dessus n'ont pas pu être supprimés. messageCasesNotDeletedExternalReason = The cases mentioned in the above list of UUIDs could not be deleted because the communication with the reporting tool failed. messageCasesDeleted = All selected eligible cases have been deleted messageCaseOutsideJurisdictionDeletionDenied = Le cas en dehors de la juridiction de l'utilisateur ne peut pas être supprimé @@ -1106,6 +1104,8 @@ messageEventGroupCreated = Nouveau groupe d'événements créé messageEventLinkedAsSuperordinate = L'événement sélectionné a été lié avec succès à cet événement en tant qu'événement supérieur messageEventLinkedAsSubordinate = L'événement sélectionné a été lié avec succès à cet événement en tant qu'événement subordonné messageEventLinkedToGroup = L'événement sélectionné a été associé avec succès à ce groupe d'événements +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = L'événement en dehors de la juridiction de l'utilisateur ne peut pas être supprimé messageEventSuperordinateEventUnlinked = Le lien entre cet événement et son événement superordonné a été supprimé avec succès messageEventSubordinateEventUnlinked = Le lien entre cet événement et son événement subordonné a été supprimé avec succès @@ -1151,7 +1151,9 @@ messageExportFailed = Il y a eu une erreur empêchant l'exportation des données messageExportConfigurationDeleted = Configuration d'export supprimée messageExportConfigurationSaved = Configuration d'exportation enregistrée messageFollowUpCanceled = Le suivi de tous les contacts sélectionnés a été annulé +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Le suivi de tous les contacts sélectionnés qui n'ont pas terminé leur suivi a été paramétré pour être perdu de vue +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = Vous avez changé le centre de santé de ce cas. Souhaitez-vous transférer le cas dans le nouvel établissement de santé (l'hospitalisation sera mise à jour) ou souhaitez-vous uniquement modifier les données pour corriger une erreur? messageFacilityMulitChanged = Vous avez changé l'établissement de santé de plusieurs cas. Souhaitez-vous transférer ces cas dans le nouvel établissement de santé (l'hospitalisation sera mise à jour) ou souhaitez-vous uniquement modifier leurs données pour corriger les erreurs? messageGdpr = Conformément au principe de minimisation des données vous devez veiller à ne saisir ici que des données adéquates, pertinentes et limitées à ce qui est nécessaire au traitement. En particulier sont interdites des données relatives à l'origine raciale ou ethnique, aux opinions politiques, aux convictions religieuses ou philosophiques ou à l'appartenance syndicale, des données génétiques, biométriques, de santé, ou des données concernant la vie sexuelle ou l'orientation sexuelle d'une personne physique, des données relatives aux condamnations pénales et aux infractions, aux mesures de sûreté connexes ou toutes autres données qui ne seraient pas en rapport avec l’enquête sanitaire. Par ailleurs, des informations relatives aux utilisateurs SORMAS sont collectées au sein de l'application et sont susceptibles d'être transmises et/ou consultées directement dans SORMAS. Pour toute information ou exercice de vos droits Informatique et Libertés, vous pouvez consulter la rubrique « A propos de ». @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Le document de la commande de quarantaine a été créé messageUnavailableTaskEditionDueToDifferentDistricts = L'édition de la tâche n'est pas disponible si elle est liée à différents départements. messageUsersEnabled = Tous les utilisateurs sélectionnés ont été activés +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = Tous les utilisateurs sélectionnés ont été désactivés +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = Ce cas est activement empêché d'être envoyé à l'outil de reporting externe messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Exportation complète vers SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = L'entrée a été envoyée à l'outil de rapport ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = Toutes les entrées sélectionnées ont été supprimées avec succès dans l'outil de rapport. ExternalSurveillanceToolGateway.notificationEntryNotSent = L'observation n’a pas pu être envoyée ExternalSurveillanceToolGateway.notificationErrorSending = Erreur lors de l'envoi du fichier diff --git a/sormas-api/src/main/resources/strings_fr-TN.properties b/sormas-api/src/main/resources/strings_fr-TN.properties index 55f8856e3a2..ae777785953 100644 --- a/sormas-api/src/main/resources/strings_fr-TN.properties +++ b/sormas-api/src/main/resources/strings_fr-TN.properties @@ -538,10 +538,8 @@ headingExportFailed = Exportation échouée headingFatalities=Fatalité headingFileExists = Dupliquer le fichier headingFilters = Filtres -headingFollowUpCanceled = Suivi annulé headingStoppedFollowUp = Suivi arrêté headingFollowUpStatus = Statut de suivi -headingFollowUpStatusChanged = Statut de suivi modifié headingHealthConditions = Antécédents médicaux headingHospitalization = Données d'hospitalisation headingPreviousHospitalizations = Hospitalisations précédentes @@ -771,8 +769,6 @@ headingCaution = Attention headingUnavailableTaskEdition = Édition de la tâche indisponible headingDeleteVaccinations = Enlever l'immunité par vaccination headingDocumentCreated = Document créé -headingUsersEnabled = Utilisateurs activés -headingUsersDisabled = Utilisateurs désactivés headingConfirmUnclearLabMessage=Confirmer la suppression headingConfirmManuallyForwardedLabMessage=Confirmation transmise headingUpdateCaseWithNewDiseaseVariant=Mettre à jour la variante de la maladie du cas @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Récupération headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Veuillez documenter toutes les activités pertinentes après l'infection \: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = La personne que vous avez sélectionnée est déjà définie comme participant à cet événement. messageAnimalContactsHint = Veuillez indiquer une réponse concernant TOUS les animaux (vivants ou morts) que la personne a eu une exposition directe (par exemple chasse, toucher, manger) pendant la période d'incubation. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = Nouveau groupe d'événements créé messageEventLinkedAsSuperordinate = L'événement sélectionné a été lié avec succès à cet événement en tant qu'événement supérieur messageEventLinkedAsSubordinate = L'événement sélectionné a été lié avec succès à cet événement en tant qu'événement subordonné messageEventLinkedToGroup = L'événement sélectionné a été associé avec succès à ce groupe d'événements +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = Le lien entre cet événement et son événement superordonné a été supprimé avec succès messageEventSubordinateEventUnlinked = Le lien entre cet événement et son événement subordonné a été supprimé avec succès @@ -1151,7 +1151,9 @@ messageExportFailed = Il y a eu une erreur empêchant l'exportation des données messageExportConfigurationDeleted = Configuration d'export supprimée messageExportConfigurationSaved = Configuration d'exportation enregistrée messageFollowUpCanceled = Le suivi de tous les contacts sélectionnés a été annulé +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Le suivi de tous les contacts sélectionnés qui n'ont pas terminé leur suivi a été paramétré pour être perdu de vue +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = Vous avez changé le centre de santé de ce cas. Souhaitez-vous transférer le cas dans le nouvel établissement de santé (l'hospitalisation sera mise à jour) ou souhaitez-vous uniquement modifier les données pour corriger une erreur? messageFacilityMulitChanged = Vous avez changé l'établissement de santé de plusieurs cas. Souhaitez-vous transférer ces cas dans le nouvel établissement de santé (l'hospitalisation sera mise à jour) ou souhaitez-vous uniquement modifier leurs données pour corriger les erreurs? messageGdpr = Conformément au principe de minimisation des données vous devez veiller à ne saisir ici que des données adéquates, pertinentes et limitées à ce qui est nécessaire au traitement. En particulier sont interdites des données relatives à l'origine raciale ou ethnique, aux opinions politiques, aux convictions religieuses ou philosophiques ou à l'appartenance syndicale, des données génétiques, biométriques, de santé, ou des données concernant la vie sexuelle ou l'orientation sexuelle d'une personne physique, des données relatives aux condamnations pénales et aux infractions, aux mesures de sûreté connexes ou toutes autres données qui ne seraient pas en rapport avec l’enquête sanitaire. Par ailleurs, des informations relatives aux utilisateurs SORMAS sont collectées au sein de l'application et sont susceptibles d'être transmises et/ou consultées directement dans SORMAS. Pour toute information ou exercice de vos droits Informatique et Libertés, vous pouvez consulter la rubrique « A propos de ». @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Le document de la commande de quarantaine a été créé messageUnavailableTaskEditionDueToDifferentDistricts = L'édition de la tâche n'est pas disponible si elle est liée à différents départements. messageUsersEnabled = Tous les utilisateurs sélectionnés ont été activés +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = Tous les utilisateurs sélectionnés ont été désactivés +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = Ce cas est activement empêché d'être envoyé à l'outil de reporting externe messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Exportation complète vers SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = L'entrée a été envoyée à l'outil de rapport ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = Toutes les entrées sélectionnées ont été supprimées avec succès dans l'outil de rapport. ExternalSurveillanceToolGateway.notificationEntryNotSent = L'observation n’a pas pu être envoyée ExternalSurveillanceToolGateway.notificationErrorSending = Erreur lors de l'envoi du fichier diff --git a/sormas-api/src/main/resources/strings_hi-IN.properties b/sormas-api/src/main/resources/strings_hi-IN.properties index 9b4de2be5d9..89f7838d10f 100644 --- a/sormas-api/src/main/resources/strings_hi-IN.properties +++ b/sormas-api/src/main/resources/strings_hi-IN.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_hr-HR.properties b/sormas-api/src/main/resources/strings_hr-HR.properties index 9b4de2be5d9..89f7838d10f 100644 --- a/sormas-api/src/main/resources/strings_hr-HR.properties +++ b/sormas-api/src/main/resources/strings_hr-HR.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_it-CH.properties b/sormas-api/src/main/resources/strings_it-CH.properties index f48dcf68299..9d9e0d26e94 100644 --- a/sormas-api/src/main/resources/strings_it-CH.properties +++ b/sormas-api/src/main/resources/strings_it-CH.properties @@ -538,10 +538,8 @@ headingExportFailed = Esportazione non riuscita headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filtri -headingFollowUpCanceled = Follow-up annullato headingStoppedFollowUp = Follow-up interrotto headingFollowUpStatus = Stato del follow-up -headingFollowUpStatusChanged = Stato del follow-up modificato headingHealthConditions = Condizioni preesistenti headingHospitalization = Dati ospedalizzazione headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = La persona che hai selezionato è già definita come partecipante di questo evento. messageAnimalContactsHint = Si prega di indicare una risposta riguardante TUTTI gli animali (vivi o morti) a cui la persona è stata esposta direttamente (p. es. cacciare, toccare, mangiare) durante il periodo di incubazione. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = Si è verificato un errore che impedisce l'esportazione de messageExportConfigurationDeleted = Configurazione di esportazione eliminata messageExportConfigurationSaved = Configurazione di esportazione salvata messageFollowUpCanceled = Il follow-up di tutti i contatti selezionati è stato annullato +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Il follow-up di tutti i contatti selezionati con follow-up è stato impostato su "Perso al follow-up" +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = Hai cambiato la struttura di questo caso. Vuoi trasferire il caso alla nuova struttura (l'ospedalizzazione verrà aggiornata) o vuoi solo modificare i dati per correggere un errore? messageFacilityMulitChanged = Hai cambiato la struttura di più casi. Vuoi trasferire questi casi alla nuova struttura (l'ospedalizzazione potrebbe essere aggiornata) o vuoi solo modificare i loro dati per correggere un errore? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_it-IT.properties b/sormas-api/src/main/resources/strings_it-IT.properties index d4969e9546a..32f2c43aa72 100644 --- a/sormas-api/src/main/resources/strings_it-IT.properties +++ b/sormas-api/src/main/resources/strings_it-IT.properties @@ -538,10 +538,8 @@ headingExportFailed = Esportazione non riuscita headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filtri -headingFollowUpCanceled = Follow-up annullato headingStoppedFollowUp = Follow-up interrotto headingFollowUpStatus = Stato del follow-up -headingFollowUpStatusChanged = Stato del follow-up modificato headingHealthConditions = Condizioni preesistenti headingHospitalization = Dati ospedalizzazione headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Si prega di indicare una risposta riguardante TUTTI gli animali (vivi o morti) a cui la persona è stata esposta direttamente (p. es. cacciare, toccare, mangiare) durante il periodo di incubazione. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = Si è verificato un errore che impedisce l'esportazione de messageExportConfigurationDeleted = Configurazione di esportazione eliminata messageExportConfigurationSaved = Configurazione di esportazione salvata messageFollowUpCanceled = Il follow-up di tutti i contatti selezionati è stato annullato +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Il follow-up di tutti i contatti selezionati con follow-up è stato impostato su "Perso al follow-up" +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_ja-JP.properties b/sormas-api/src/main/resources/strings_ja-JP.properties index 9b4de2be5d9..89f7838d10f 100644 --- a/sormas-api/src/main/resources/strings_ja-JP.properties +++ b/sormas-api/src/main/resources/strings_ja-JP.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_ne-NP.properties b/sormas-api/src/main/resources/strings_ne-NP.properties index 4b357d2941e..e4236d4d812 100644 --- a/sormas-api/src/main/resources/strings_ne-NP.properties +++ b/sormas-api/src/main/resources/strings_ne-NP.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Current Hospitalization headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_nl-NL.properties b/sormas-api/src/main/resources/strings_nl-NL.properties index 9b4de2be5d9..89f7838d10f 100644 --- a/sormas-api/src/main/resources/strings_nl-NL.properties +++ b/sormas-api/src/main/resources/strings_nl-NL.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_no-NO.properties b/sormas-api/src/main/resources/strings_no-NO.properties index 9b4de2be5d9..89f7838d10f 100644 --- a/sormas-api/src/main/resources/strings_no-NO.properties +++ b/sormas-api/src/main/resources/strings_no-NO.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_pl-PL.properties b/sormas-api/src/main/resources/strings_pl-PL.properties index 8f9c3fc6eb6..eefff346401 100644 --- a/sormas-api/src/main/resources/strings_pl-PL.properties +++ b/sormas-api/src/main/resources/strings_pl-PL.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_ps-AF.properties b/sormas-api/src/main/resources/strings_ps-AF.properties index db7ee5df789..3594e9ea38a 100644 --- a/sormas-api/src/main/resources/strings_ps-AF.properties +++ b/sormas-api/src/main/resources/strings_ps-AF.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_pt-PT.properties b/sormas-api/src/main/resources/strings_pt-PT.properties index 9b4de2be5d9..89f7838d10f 100644 --- a/sormas-api/src/main/resources/strings_pt-PT.properties +++ b/sormas-api/src/main/resources/strings_pt-PT.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_ro-RO.properties b/sormas-api/src/main/resources/strings_ro-RO.properties index 9b4de2be5d9..89f7838d10f 100644 --- a/sormas-api/src/main/resources/strings_ro-RO.properties +++ b/sormas-api/src/main/resources/strings_ro-RO.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_ru-RU.properties b/sormas-api/src/main/resources/strings_ru-RU.properties index e39f41f48ef..9ddc4075ce0 100644 --- a/sormas-api/src/main/resources/strings_ru-RU.properties +++ b/sormas-api/src/main/resources/strings_ru-RU.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_sv-SE.properties b/sormas-api/src/main/resources/strings_sv-SE.properties index 9b4de2be5d9..89f7838d10f 100644 --- a/sormas-api/src/main/resources/strings_sv-SE.properties +++ b/sormas-api/src/main/resources/strings_sv-SE.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_sw-KE.properties b/sormas-api/src/main/resources/strings_sw-KE.properties index 9b4de2be5d9..89f7838d10f 100644 --- a/sormas-api/src/main/resources/strings_sw-KE.properties +++ b/sormas-api/src/main/resources/strings_sw-KE.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_tr-TR.properties b/sormas-api/src/main/resources/strings_tr-TR.properties index 9b4de2be5d9..89f7838d10f 100644 --- a/sormas-api/src/main/resources/strings_tr-TR.properties +++ b/sormas-api/src/main/resources/strings_tr-TR.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_uk-UA.properties b/sormas-api/src/main/resources/strings_uk-UA.properties index 9b4de2be5d9..89f7838d10f 100644 --- a/sormas-api/src/main/resources/strings_uk-UA.properties +++ b/sormas-api/src/main/resources/strings_uk-UA.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-api/src/main/resources/strings_ur-PK.properties b/sormas-api/src/main/resources/strings_ur-PK.properties index 2d29123dfec..7e6fdccb82a 100644 --- a/sormas-api/src/main/resources/strings_ur-PK.properties +++ b/sormas-api/src/main/resources/strings_ur-PK.properties @@ -538,10 +538,8 @@ headingExportFailed = ایکسپورٹ ناکام ہوا headingFatalities=ہلاکتیں headingFileExists = ڈپلیکیٹ فائل headingFilters = فلٹرز -headingFollowUpCanceled = فالو اپ منسوخ کر دیا گیا headingStoppedFollowUp = فالو اپ روک دیا گیا headingFollowUpStatus = فالو اپ کی حالت -headingFollowUpStatusChanged = فالو اپ کی حالت بدل گئی headingHealthConditions = پہلے سے موجود حالات headingHospitalization = موجودہ ہسپتال میں داخلہ headingPreviousHospitalizations = گزشتہ ہسپتال میں داخلے @@ -771,8 +769,6 @@ headingCaution = انتباہ headingUnavailableTaskEdition = غیر دستیاب ٹاسک ایڈیشن headingDeleteVaccinations = امیونائزیشن کی ویکسین کو مٹا دیں headingDocumentCreated = دستاویز بنائی گئی -headingUsersEnabled = صارفین فعال ہیں -headingUsersDisabled = صارفین کو غیر فعال کر دیا گیا headingConfirmUnclearLabMessage=غیر واضح کی تصدیق کریں headingConfirmManuallyForwardedLabMessage=آگے بھیجنے کی تصدیق کریں headingUpdateCaseWithNewDiseaseVariant=کیس کی بیماری کے مختلف قسم کو اپ ڈیٹ کریں @@ -809,6 +805,7 @@ immunizationVaccinationHeading = ویکسینیشن immunizationRecoveryHeading = بازیابی headingAutomaticDeletionStarted = خودکار حذف مٹانا شروع ہو گیا headingBulkOperationProgress = بلک آپریشن کی پیشرفت میں +headingSomeContactsAlreadyInEvent = کچھ رابطے پہلے ہی تقریب سے منسلک ہیں # Info texts infoActivityAsCaseInvestigation = براہ کرم انفیکشن کے بعد تمام متعلقہ سرگرمیوں کو دستاویز کریں\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = تمام کیسز پہلے ہی منتخب تق messageAllCasesLinkedToEvent = تمام کیسز کو منتخب تقریب سے جوڑ دیا گیا ہے۔ messageAllContactsAlreadyInEvent = تمام رابطے پہلے سے ہی منتخب تقریب سے منسلک ہیں۔ messageAllContactsLinkedToEvent = تمام رابطوں کو منتخب تقریب سے منسلک کر دیا گیا ہے۔ +messageSomeContactsLinkedToEvent = کچھ منتخب رابطوں کو منتخب تقریب سے منسلک کر دیا گیا ہے۔ messageAlreadyEventParticipant = آپ نے جس شخص کو منتخب کیا ہے اس کی پہلے سے ہی اس تقریب کے ایک شرکت کنندہ کے طور پر بتایا کی گئی ہے۔ messageAnimalContactsHint = براہ کرم ان تمام جانوروں (زندہ یا مردہ) کے بارے میں ایک جواب کی نشاندہی کریں جو انکیوبیشن کی مدت کے دوران اس شخص سے براہ راست متاثر ہوا تھا (مثلاً شکار، چھونا، کھانا)۔ messageArchiveUndoneReasonMandatory = براہ کرم ڈی آرکائیو کرنے کی وجہ شامل کریں @@ -1106,6 +1104,8 @@ messageEventGroupCreated = نیا تقریبی گروہ بنایا گیا messageEventLinkedAsSuperordinate = منتخب تقریب کو کامیابی کے ساتھ اس تقریب سے اس کے اعلیٰ ترین تقریب کے طور پر منسلک کر دیا گیا messageEventLinkedAsSubordinate = منتخب تقریب کو ماتحت تقریب کے طور پر کامیابی کے ساتھ اس تقریب سے منسلک کر دیا گیا messageEventLinkedToGroup = منتخب کردہ تقریب کو کامیابی کے ساتھ اس تقریبی گروہ سے منسلک کر دیا گیا تھا۔ +messageEventsLinkedToGroup = منتخب تقریبات کو کامیابی کے ساتھ اس تقریبی گروپ سے منسلک کر دیا گیا ہے +messageSomeEventsLinkedToGroup = کچھ منتخب تقریبات کو کامیابی کے ساتھ اس تقریبی گروپ سے منسلک کر دیا گیا ہے messageEventOutsideJurisdictionDeletionDenied = صارف کے دائرہ اختیار سے باہر کو تقریب حذف نہیں کیا جا سکتا messageEventSuperordinateEventUnlinked = اس تقریب اور اس کے اعلیٰ ترین تقریب کے درمیان تعلق کو کامیابی کے ساتھ ہٹا دیا گیا۔ messageEventSubordinateEventUnlinked = اس تقریب اور اس کے ماتحت تقریب کے درمیان تعلق کو کامیابی کے ساتھ ہٹا دیا گیا تھا @@ -1151,7 +1151,9 @@ messageExportFailed = ڈیٹا کو ایکسپورٹ کرنے سے روکنے م messageExportConfigurationDeleted = ايکسپورٹ کنفیگریشن مٹا دی گئ messageExportConfigurationSaved = ایکسپورٹ کنفیگریشن محفوظ ہو گئی messageFollowUpCanceled = تمام منتخب رابطوں کا فالو اپ منسوخ کر دیا گیا ہے +messageFollowUpCanceledForSome = کچھ منتخب رابطوں کا فالو اپ منسوخ کر دیا گیا ہے messageFollowUpStatusChanged = ان تمام منتخب رابطوں کا فالو اپ جن کا فالو اپ ہے فالو اپ کو ختم کرنے کے لیے سیٹ کیا گیا ہے +messageFollowUpStatusChangedForSome = کچھ منتخب رابطوں کا فالو اپ جن کا فالو اپ ہے فالو اپ کو ختم کرنے کے لیے سیٹ کر دیا گیا ہے۔ messageFacilityChanged = آپ نے اس کیس کی سہولت گاہ تبدیل کر دی ہے۔ کیا آپ کیس کو نئی سہولت گاہ میں منتقل کرنا چاہتے ہیں (ہسپتال میں داخلے کو اپ ڈیٹ کیا جا سکتا ہے) یا آپ غلطی کو درست کرنے کے لیے صرف ڈیٹا میں ترمیم کرنا چاہتے ہیں؟ messageFacilityMulitChanged = آپ نے متعدد کیسز کی سہولت گاہ کو تبدیل کیا ہے۔ کیا آپ ان کیسز کو نئی سہولت گاہ میں منتقل کرنا چاہتے ہیں (ہسپتال میں داخلے کو اپ ڈیٹ کیا جا سکتا ہے) یا آپ غلطیوں کو درست کرنے کے لیے صرف ان کے ڈیٹا میں ترمیم کرنا چاہتے ہیں؟ messageGdpr = GDPR کی طرف سے لاگو کردہ ڈیٹا مائنسائزیشن کے اصول کے مطابق، آپ کو یقینی بنانا چاہیے کہ آپ یہاں صرف وہی معروضی ڈیٹا درج کریں جو فائل کی پروسیسنگ کے لیے بالکل ضروری ہے۔ خاص طور پر، آپ کو جینیاتی یا بائیو میٹرک، فلسفیانہ، سیاسی، مذہبی ڈیٹا، یونین کی رائے، جنسی زندگی یا رجحان، نسلی اصل، جرائم، سزائیں، حفاظتی اقدامات، مجرمانہ ریکارڈ... یا کوئی دوسرا ڈیٹا درج نہیں کرنا چاہیے جس کا تعلق عوامی صحت کی نگرانی سے نہ ہو۔ @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = تمام منتخب کردہ اہل پیغام messageQuarantineOrderDocumentCreated = قرنطینہ آرڈر کی دستاویز بنا دی گئی ہے messageUnavailableTaskEditionDueToDifferentDistricts = اگر وہ مختلف اضلاع سے متعلق ہیں تو ٹاسک ایڈیشن دستیاب نہیں ہے messageUsersEnabled = تمام منتخب صارفین کو فعال کر دیا گیا ہے +messageSomeUsersEnabled = منتخب کردہ صارفین میں سے کچھ کو فعال کر دیا گیا ہے messageUsersDisabled = تمام منتخب صارفین کو غیر فعال کر دیا گیا ہے +messageSomeUsersDisabled = کچھ منتخب صارفین کو غیر فعال کر دیا گیا ہے messageDontShareWithReportingToolWarning = اس کیس کو فعال طور پر بیرونی رپورٹنگ ٹول کو بھیجے جانے سے روک دیا گیا ہے messageBulkCasesWithDifferentDiseasesSelected = آپ نے مختلف بیماریوں والے کیسز کا انتخاب کیا ہے۔ کچھ بڑی تعداد میں ترمیم کے اختیارات دستیاب نہیں ہو سکتے ہیں۔ messageBulkContactsWithDifferentDiseasesSelected = آپ نے مختلف بیماریوں والے روابط کا انتخاب کیا ہے۔ کچھ بڑی تعداد میں ترمیم کے اختیارات دستیاب نہیں ہو سکتے ہیں۔ @@ -1589,6 +1593,7 @@ infoBAGExport=SEDEX کو مکمل ایکسپورٹ کریں # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = رپورٹنگ ٹول پر اندراج بھیج دیا گیا ہے ExternalSurveillanceToolGateway.notificationEntriesSent = تمام منتخب اندراجات رپورٹنگ ٹول کو بھیج دیے گئے ہیں. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = کچھ منتخب اندراجات رپورٹنگ ٹول کو بھیج دیے گئے ہیں۔ ExternalSurveillanceToolGateway.notificationEntriesDeleted = رپورٹنگ ٹول میں تمام منتخب اندراجات کو کامیابی کے ساتھ مٹا دیا گیا ہے۔ ExternalSurveillanceToolGateway.notificationEntryNotSent = اندراج نہیں بھیجا جا سکا ExternalSurveillanceToolGateway.notificationErrorSending = اندراج بھیجتے وقت خرابی diff --git a/sormas-api/src/main/resources/strings_zh-CN.properties b/sormas-api/src/main/resources/strings_zh-CN.properties index 4338621e08a..ed92020e2aa 100644 --- a/sormas-api/src/main/resources/strings_zh-CN.properties +++ b/sormas-api/src/main/resources/strings_zh-CN.properties @@ -538,10 +538,8 @@ headingExportFailed = Export failed headingFatalities=Fatalities headingFileExists = Duplicate File headingFilters = Filters -headingFollowUpCanceled = Follow-up canceled headingStoppedFollowUp = Stopped Follow-up headingFollowUpStatus = Follow-up status -headingFollowUpStatusChanged = Follow-up status changed headingHealthConditions = Pre-existing conditions headingHospitalization = Hospitalization data headingPreviousHospitalizations = Previous Hospitalizations @@ -771,8 +769,6 @@ headingCaution = Caution headingUnavailableTaskEdition = Unavailable task edition headingDeleteVaccinations = Remove immunization vaccinations headingDocumentCreated = Document created -headingUsersEnabled = Users enabled -headingUsersDisabled = Users disabled headingConfirmUnclearLabMessage=Confirm unclear headingConfirmManuallyForwardedLabMessage=Confirm forwarded headingUpdateCaseWithNewDiseaseVariant=Update case disease variant @@ -809,6 +805,7 @@ immunizationVaccinationHeading = Vaccination immunizationRecoveryHeading = Recovery headingAutomaticDeletionStarted = Automatic deletion started headingBulkOperationProgress = Bulk operation progress +headingSomeContactsAlreadyInEvent = Some contacts are already linked to the event # Info texts infoActivityAsCaseInvestigation = Please document ALL relevant activities after infection\: @@ -1019,6 +1016,7 @@ messageAllCasesAlreadyInEvent = All cases are already linked to the selected eve messageAllCasesLinkedToEvent = All cases have been linked to the selected event. messageAllContactsAlreadyInEvent = All contacts are already linked to the selected event. messageAllContactsLinkedToEvent = All contacts have been linked to the selected event. +messageSomeContactsLinkedToEvent = Some of the selected contacts have been linked to the selected event. messageAlreadyEventParticipant = The person you have selected is already defined as an event participant of this event. messageAnimalContactsHint = Please indicate an answer regarding ALL animals (live or dead) the person had direct exposure to (e.g. hunt, touch, eat) during the incubation period. messageArchiveUndoneReasonMandatory = Please add a reason for de-archiving @@ -1106,6 +1104,8 @@ messageEventGroupCreated = New event group created messageEventLinkedAsSuperordinate = The selected event was successfully linked to this event as its superordinate event messageEventLinkedAsSubordinate = The selected event was successfully linked to this event as a subordinate event messageEventLinkedToGroup = The selected event was successfully linked to this event group +messageEventsLinkedToGroup = The selected events hav been successfully linked to this event group +messageSomeEventsLinkedToGroup = Some of the selected events have been successfully linked to this event group messageEventOutsideJurisdictionDeletionDenied = The event outside user's jurisdiction cannot be deleted messageEventSuperordinateEventUnlinked = The link between this event and its superordinate event was successfully removed messageEventSubordinateEventUnlinked = The link between this event and its subordinate event was successfully removed @@ -1151,7 +1151,9 @@ messageExportFailed = There was an error preventing the data to be exported. Ple messageExportConfigurationDeleted = Export configuration deleted messageExportConfigurationSaved = Export configuration saved messageFollowUpCanceled = Follow-up of all selected contacts has been canceled +messageFollowUpCanceledForSome = Follow-up of some selected contacts has been canceled messageFollowUpStatusChanged = Follow-up of all selected contacts that have follow-up has been set to lost to follow-up +messageFollowUpStatusChangedForSome = Follow-up of some selected contacts that have follow-up has been set to lost to follow-up messageFacilityChanged = You have changed the facility of this case. Do you want to transfer the case to the new facility (the hospitalization may be updated) or do you only want to edit the data to correct a mistake? messageFacilityMulitChanged = You have changed the facility of multiple cases. Do you want to transfer these cases to the new facility (the hospitalization may be updated) or do you only want to edit their data to correct mistakes? messageGdpr = In accordance with the principle of data minimization imposed by the GDPR, you must ensure that you enter here only objective data absolutely necessary for the processing of the file. In particular, you must not enter genetic or biometric, philosophical, political, religious data, union opinions, sexual life or orientation, ethnic origin, offenses, convictions, security measures, criminal record ... or any other data that is not related to public health surveillance. @@ -1347,7 +1349,9 @@ messageExternalMessagesDeleted = All selected eligible messages have been delete messageQuarantineOrderDocumentCreated = Quarantine order document has been created messageUnavailableTaskEditionDueToDifferentDistricts = Task edition is not available if they are related to different districts messageUsersEnabled = All selected users have been enabled +messageSomeUsersEnabled = Some of the selected users have been enabled messageUsersDisabled = All selected users have been disabled +messageSomeUsersDisabled = Some of the selected users have been disabled messageDontShareWithReportingToolWarning = This case is actively prevented from being sent to the external reporting tool messageBulkCasesWithDifferentDiseasesSelected = You have selected cases with different diseases. Some bulk edit options might be unavailable. messageBulkContactsWithDifferentDiseasesSelected = You have selected contacts with different diseases. Some bulk edit options might be unavailable. @@ -1589,6 +1593,7 @@ infoBAGExport=Full-Export to SEDEX # Survnet Gateway ExternalSurveillanceToolGateway.notificationEntrySent = Entry has been sent to the reporting tool ExternalSurveillanceToolGateway.notificationEntriesSent = All selected entries have been sent to the reporting tool. +ExternalSurveillanceToolGateway.notificationSomeEntriesSent = Some of the selected entries have been sent to the reporting tool. ExternalSurveillanceToolGateway.notificationEntriesDeleted = All selected entries have been successfully deleted in the reporting tool. ExternalSurveillanceToolGateway.notificationEntryNotSent = Entry could not be sent ExternalSurveillanceToolGateway.notificationErrorSending = Error when sending entry diff --git a/sormas-app/app/src/main/res/values-ar-rSA/strings.xml b/sormas-app/app/src/main/res/values-ar-rSA/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-ar-rSA/strings.xml +++ b/sormas-app/app/src/main/res/values-ar-rSA/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-cs-rCZ/strings.xml b/sormas-app/app/src/main/res/values-cs-rCZ/strings.xml index 0ab92802b58..ef6d764648a 100644 --- a/sormas-app/app/src/main/res/values-cs-rCZ/strings.xml +++ b/sormas-app/app/src/main/res/values-cs-rCZ/strings.xml @@ -381,6 +381,7 @@ Číst vzorek Shrnutí vzorku Seznam vzorků + Environment Listing Upravit imunizaci Nová imunizace Číst imunizaci @@ -501,6 +502,7 @@ Události Zprávy Vzorky + Environments Imunizace Nastavení Úkoly @@ -652,6 +654,7 @@ Datum léčby N/A Typ N/A ID N/A + ExternalID N/A Datum návštěvy N/A Poznámky N/A Čas návštěvy N/A diff --git a/sormas-app/app/src/main/res/values-de-rCH/strings.xml b/sormas-app/app/src/main/res/values-de-rCH/strings.xml index c10f381c881..815cbea1080 100644 --- a/sormas-app/app/src/main/res/values-de-rCH/strings.xml +++ b/sormas-app/app/src/main/res/values-de-rCH/strings.xml @@ -381,6 +381,7 @@ Probe lesen Probe-Zusammenfassung Proben-Liste + Environment Listing Immunisierung bearbeiten Neue Immunisierung Immunisierung lesen @@ -501,6 +502,7 @@ Ereignisse Meldungen Proben + Environments Immunisierungen Einstellungen Aufgaben @@ -652,6 +654,7 @@ Behandlungsdatum N/A Typ N/A ID N/A + ExternalID N/A Anrufsdatum N/A Anmerkungen N/A Anrufszeit N/A diff --git a/sormas-app/app/src/main/res/values-de-rDE/strings.xml b/sormas-app/app/src/main/res/values-de-rDE/strings.xml index e402a364e56..e6450012d39 100644 --- a/sormas-app/app/src/main/res/values-de-rDE/strings.xml +++ b/sormas-app/app/src/main/res/values-de-rDE/strings.xml @@ -381,6 +381,7 @@ Probe lesen Probe-Zusammenfassung Proben-Liste + Environment Listing Immunisierung bearbeiten Neue Immunisierung Immunisierung lesen @@ -501,6 +502,7 @@ Ereignisse Meldungen Proben + Environments Immunisierungen Einstellungen Aufgaben @@ -652,6 +654,7 @@ Behandlungsdatum N/A Typ N/A ID N/A + ExternalID N/A Anrufsdatum N/A Anmerkungen N/A Anrufszeit N/A diff --git a/sormas-app/app/src/main/res/values-en-rAF/strings.xml b/sormas-app/app/src/main/res/values-en-rAF/strings.xml index 48b6baed0f5..aa677bdb348 100644 --- a/sormas-app/app/src/main/res/values-en-rAF/strings.xml +++ b/sormas-app/app/src/main/res/values-en-rAF/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-en-rGH/strings.xml b/sormas-app/app/src/main/res/values-en-rGH/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-en-rGH/strings.xml +++ b/sormas-app/app/src/main/res/values-en-rGH/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-en-rNG/strings.xml b/sormas-app/app/src/main/res/values-en-rNG/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-en-rNG/strings.xml +++ b/sormas-app/app/src/main/res/values-en-rNG/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-es-rCU/strings.xml b/sormas-app/app/src/main/res/values-es-rCU/strings.xml index 50ff94eea06..992854aa929 100644 --- a/sormas-app/app/src/main/res/values-es-rCU/strings.xml +++ b/sormas-app/app/src/main/res/values-es-rCU/strings.xml @@ -381,6 +381,7 @@ Leer muestra Resumen de la muestra Listado de muestras + Listado de ambientes Editar inmunización Nueva inmunización Leer inmunización @@ -501,6 +502,7 @@ Eventos Informes Muestras + Ambientes Inmunizaciones Ajustes Tareas @@ -652,6 +654,7 @@ Fecha del tratamiento N/D Tipo N/D ID N/D + ExternalID N/A Fecha de la visita N/D Observaciones N/D Hora de la visita N/D diff --git a/sormas-app/app/src/main/res/values-es-rES/strings.xml b/sormas-app/app/src/main/res/values-es-rES/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-es-rES/strings.xml +++ b/sormas-app/app/src/main/res/values-es-rES/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-fa-rAF/strings.xml b/sormas-app/app/src/main/res/values-fa-rAF/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-fa-rAF/strings.xml +++ b/sormas-app/app/src/main/res/values-fa-rAF/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-fi-rFI/strings.xml b/sormas-app/app/src/main/res/values-fi-rFI/strings.xml index 756e595869a..048b8b354a0 100644 --- a/sormas-app/app/src/main/res/values-fi-rFI/strings.xml +++ b/sormas-app/app/src/main/res/values-fi-rFI/strings.xml @@ -381,6 +381,7 @@ Lue näyte Näytteen yhteenveto Näytelistaus + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Ilmoitukset Raportit Näytteet + Environments Immunizations Asetukset Tehtävät @@ -652,6 +654,7 @@ Hoitopäivämäärä puuttuu Tyyppi puuttuu ID puuttuu + ExternalID N/A Käyntipäivämäärä puuttuu Huomiot puuttuvat Käyntiaika puuttuu diff --git a/sormas-app/app/src/main/res/values-fil-rPH/strings.xml b/sormas-app/app/src/main/res/values-fil-rPH/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-fil-rPH/strings.xml +++ b/sormas-app/app/src/main/res/values-fil-rPH/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-fj-rFJ/strings.xml b/sormas-app/app/src/main/res/values-fj-rFJ/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-fj-rFJ/strings.xml +++ b/sormas-app/app/src/main/res/values-fj-rFJ/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-fr-rCD/strings.xml b/sormas-app/app/src/main/res/values-fr-rCD/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-fr-rCD/strings.xml +++ b/sormas-app/app/src/main/res/values-fr-rCD/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-fr-rCH/strings.xml b/sormas-app/app/src/main/res/values-fr-rCH/strings.xml index 2dad3d064d6..0dba352c6db 100644 --- a/sormas-app/app/src/main/res/values-fr-rCH/strings.xml +++ b/sormas-app/app/src/main/res/values-fr-rCH/strings.xml @@ -381,6 +381,7 @@ Lire l\'échantillon Résumé de l\'échantillon Liste d\'échantillons + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Évènements Rapports Échantillons + Environments Immunizations Paramètres Tâches @@ -652,6 +654,7 @@ Date de traitement N/A Type N/A ID N/A + ExternalID N/A Date de visite N/A Remarques N/A Date de visite N/A diff --git a/sormas-app/app/src/main/res/values-fr-rFR/strings.xml b/sormas-app/app/src/main/res/values-fr-rFR/strings.xml index edfce4c7456..970b077704a 100644 --- a/sormas-app/app/src/main/res/values-fr-rFR/strings.xml +++ b/sormas-app/app/src/main/res/values-fr-rFR/strings.xml @@ -381,6 +381,7 @@ Lire l\'échantillon Résumé de l\'échantillon Liste d\'échantillons + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Évènements Rapports Échantillons + Environments Immunizations Paramètres Tâches @@ -652,6 +654,7 @@ Date de traitement N/A Type N/A ID N/A + ExternalID N/A Date de visite N/A Remarques N/A Date de visite N/A diff --git a/sormas-app/app/src/main/res/values-fr-rTN/strings.xml b/sormas-app/app/src/main/res/values-fr-rTN/strings.xml index edfce4c7456..970b077704a 100644 --- a/sormas-app/app/src/main/res/values-fr-rTN/strings.xml +++ b/sormas-app/app/src/main/res/values-fr-rTN/strings.xml @@ -381,6 +381,7 @@ Lire l\'échantillon Résumé de l\'échantillon Liste d\'échantillons + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Évènements Rapports Échantillons + Environments Immunizations Paramètres Tâches @@ -652,6 +654,7 @@ Date de traitement N/A Type N/A ID N/A + ExternalID N/A Date de visite N/A Remarques N/A Date de visite N/A diff --git a/sormas-app/app/src/main/res/values-hi-rIN/strings.xml b/sormas-app/app/src/main/res/values-hi-rIN/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-hi-rIN/strings.xml +++ b/sormas-app/app/src/main/res/values-hi-rIN/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-hr-rHR/strings.xml b/sormas-app/app/src/main/res/values-hr-rHR/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-hr-rHR/strings.xml +++ b/sormas-app/app/src/main/res/values-hr-rHR/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-it-rCH/strings.xml b/sormas-app/app/src/main/res/values-it-rCH/strings.xml index d57dd439430..1c5af35ebf7 100644 --- a/sormas-app/app/src/main/res/values-it-rCH/strings.xml +++ b/sormas-app/app/src/main/res/values-it-rCH/strings.xml @@ -381,6 +381,7 @@ Lettura Campione Riepilogo Campione Elenco Campioni + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Eventi Rapporti Campioni + Environments Immunizations Impostazioni Attività @@ -652,6 +654,7 @@ Data Di Trattamento N/A Tipo N/A ID N/A + ExternalID N/A Data Di Visita N/A Osservazioni N/A Data Di Visita N/A diff --git a/sormas-app/app/src/main/res/values-it-rIT/strings.xml b/sormas-app/app/src/main/res/values-it-rIT/strings.xml index 61d65814820..bbaf16aa6d5 100644 --- a/sormas-app/app/src/main/res/values-it-rIT/strings.xml +++ b/sormas-app/app/src/main/res/values-it-rIT/strings.xml @@ -381,6 +381,7 @@ Lettura Campione Riepilogo Campione Elenco Campioni + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Eventi Rapporti Campioni + Environments Immunizations Impostazioni Attività @@ -652,6 +654,7 @@ Data Di Trattamento N/A Tipo N/A ID N/A + ExternalID N/A Data Di Visita N/A Osservazioni N/A Data Di Visita N/A diff --git a/sormas-app/app/src/main/res/values-ja-rJP/strings.xml b/sormas-app/app/src/main/res/values-ja-rJP/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-ja-rJP/strings.xml +++ b/sormas-app/app/src/main/res/values-ja-rJP/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-ne-rNP/strings.xml b/sormas-app/app/src/main/res/values-ne-rNP/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-ne-rNP/strings.xml +++ b/sormas-app/app/src/main/res/values-ne-rNP/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-nl-rNL/strings.xml b/sormas-app/app/src/main/res/values-nl-rNL/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-nl-rNL/strings.xml +++ b/sormas-app/app/src/main/res/values-nl-rNL/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-no-rNO/strings.xml b/sormas-app/app/src/main/res/values-no-rNO/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-no-rNO/strings.xml +++ b/sormas-app/app/src/main/res/values-no-rNO/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-pl-rPL/strings.xml b/sormas-app/app/src/main/res/values-pl-rPL/strings.xml index cc0a518b5d2..4aa8c91416f 100644 --- a/sormas-app/app/src/main/res/values-pl-rPL/strings.xml +++ b/sormas-app/app/src/main/res/values-pl-rPL/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-ps-rAF/strings.xml b/sormas-app/app/src/main/res/values-ps-rAF/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-ps-rAF/strings.xml +++ b/sormas-app/app/src/main/res/values-ps-rAF/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-pt-rPT/strings.xml b/sormas-app/app/src/main/res/values-pt-rPT/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-pt-rPT/strings.xml +++ b/sormas-app/app/src/main/res/values-pt-rPT/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-ro-rRO/strings.xml b/sormas-app/app/src/main/res/values-ro-rRO/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-ro-rRO/strings.xml +++ b/sormas-app/app/src/main/res/values-ro-rRO/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-ru-rRU/strings.xml b/sormas-app/app/src/main/res/values-ru-rRU/strings.xml index 946b4407611..2d4e60a1724 100644 --- a/sormas-app/app/src/main/res/values-ru-rRU/strings.xml +++ b/sormas-app/app/src/main/res/values-ru-rRU/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-sv-rSE/strings.xml b/sormas-app/app/src/main/res/values-sv-rSE/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-sv-rSE/strings.xml +++ b/sormas-app/app/src/main/res/values-sv-rSE/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-sw-rKE/strings.xml b/sormas-app/app/src/main/res/values-sw-rKE/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-sw-rKE/strings.xml +++ b/sormas-app/app/src/main/res/values-sw-rKE/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-tr-rTR/strings.xml b/sormas-app/app/src/main/res/values-tr-rTR/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-tr-rTR/strings.xml +++ b/sormas-app/app/src/main/res/values-tr-rTR/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-uk-rUA/strings.xml b/sormas-app/app/src/main/res/values-uk-rUA/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-uk-rUA/strings.xml +++ b/sormas-app/app/src/main/res/values-uk-rUA/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A diff --git a/sormas-app/app/src/main/res/values-ur-rPK/strings.xml b/sormas-app/app/src/main/res/values-ur-rPK/strings.xml index 8c3614590ab..5e02bf8732b 100644 --- a/sormas-app/app/src/main/res/values-ur-rPK/strings.xml +++ b/sormas-app/app/src/main/res/values-ur-rPK/strings.xml @@ -381,6 +381,7 @@ نمونہ پڑھیں نمونہ کا خلاصہ نمونہ کی فہرست + ماحولیات کی فہرست امیونائزیشن میں ترمیم کریں نئی امیونائزیشن امیونائزیشن پڑھیں @@ -501,6 +502,7 @@ تقریبات رپورٹس نمونے + ماحولیات امیونائزیشنز ترتیبات کام @@ -652,6 +654,7 @@ علاج کی تاریخ دستیاب نہیں ہے قسم دستیاب نہیں ہے شناخت دستیاب نہیں ہے + بیرونی ID دستیاب نہیں ہے دورہ کی تاریخ دستیاب نہیں ہے ریمارکس دستیاب نہیں ہیں۔ وزٹ کا وقت دستیاب نہیں ہے diff --git a/sormas-app/app/src/main/res/values-zh-rCN/strings.xml b/sormas-app/app/src/main/res/values-zh-rCN/strings.xml index 920cf0dba48..584650e1921 100644 --- a/sormas-app/app/src/main/res/values-zh-rCN/strings.xml +++ b/sormas-app/app/src/main/res/values-zh-rCN/strings.xml @@ -381,6 +381,7 @@ Read Sample Sample Summary Sample Listing + Environment Listing Edit Immunization New Immunization Read Immunization @@ -501,6 +502,7 @@ Events Reports Samples + Environments Immunizations Settings Tasks @@ -652,6 +654,7 @@ Treatment Date N/A Type N/A ID N/A + ExternalID N/A Visit Date N/A Remarks N/A Visit Time N/A From 680f90f8f96443e6220ed6a6a4eb3d609574df66 Mon Sep 17 00:00:00 2001 From: Levente Gal Date: Thu, 3 Aug 2023 15:39:36 +0300 Subject: [PATCH 165/174] #11464 Bulk process window for send to external surv tool - don't show failed bathes as skiped, stop the process and show an error instead, to be consistent with other bulk processes --- .../ExternalSurveillanceServiceGateway.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalsurveillanceservice/ExternalSurveillanceServiceGateway.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalsurveillanceservice/ExternalSurveillanceServiceGateway.java index d86cbd0e5cf..fc952002b69 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalsurveillanceservice/ExternalSurveillanceServiceGateway.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalsurveillanceservice/ExternalSurveillanceServiceGateway.java @@ -131,7 +131,7 @@ public static void sendCasesToExternalSurveillanceTool( FacadeProvider.getExternalSurveillanceToolFacade() .sendCases(batch.stream().map(CaseIndexDto::getUuid).collect(Collectors.toList())); } catch (ExternalSurveillanceToolException e) { - return 0; + throw new RuntimeException(e); } return batch.size(); From 9ea2e594ace2136a79de19733ff98b369a0c1857 Mon Sep 17 00:00:00 2001 From: Michal Kozakiewicz Date: Thu, 3 Aug 2023 15:59:01 +0200 Subject: [PATCH 166/174] SORQA-1051 Implement "Check Hospitalization of case when sending from SORMAS to Meldesoftware" -added tests that check Hospitalization --- .../enums/ReasonForHospitalization.java | 53 +++ .../entities/services/CaseService.java | 18 + .../services/HospitalizationService.java | 21 ++ .../PreviousHospitalizationService.java | 23 ++ .../application/cases/CreateNewCaseSteps.java | 18 + .../cases/HospitalizationTabSteps.java | 80 +++-- .../cases/PreviousHospitalizationSteps.java | 96 ++++-- .../web/application/survnet/SurvNetSteps.java | 307 ++++++++++++++++++ .../features/sanity/web/Survnet.feature | 46 ++- 9 files changed, 621 insertions(+), 41 deletions(-) create mode 100644 sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/ReasonForHospitalization.java diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/ReasonForHospitalization.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/ReasonForHospitalization.java new file mode 100644 index 00000000000..48b4f0d0e50 --- /dev/null +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/enums/ReasonForHospitalization.java @@ -0,0 +1,53 @@ +/* + * SORMAS® - Surveillance Outbreak Response Management & Analysis System + * Copyright © 2016-2023 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sormas.e2etests.enums; + +import java.util.Random; +import lombok.Getter; + +@Getter +public enum ReasonForHospitalization { + REPORTEDDISEASE("Reported disease", "Gemeldete Krankheit"), + ISOLATION("Isolation", "Isolation"), + OTHERREASON("Other reason", "Anderer Grund"), + UNKNOWN("Unknown", "Unbekannt"); + + private final String reasonForHospitalization; + private final String reasonForHospitalizationDE; + + ReasonForHospitalization( + String genericReasonForHospitalization, String genericReasonForHospitalizationDEE) { + reasonForHospitalization = genericReasonForHospitalization; + reasonForHospitalizationDE = genericReasonForHospitalizationDEE; + } + + public static String getRandomReasonForHospitalization() { + Random random = new Random(); + return String.valueOf( + ReasonForHospitalization.values()[random.nextInt(values().length)] + .reasonForHospitalization); + } + + public static String getRandomReasonForHospitalizationDE() { + Random random = new Random(); + return String.valueOf( + ReasonForHospitalization.values()[random.nextInt(values().length)] + .reasonForHospitalizationDE); + } +} diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/CaseService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/CaseService.java index 7cace4a4826..3fff28f9c20 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/CaseService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/CaseService.java @@ -598,6 +598,24 @@ public Case buildCaseForSurvnetFeature() { .build(); } + public Case buildCaseWithFacilitiesForSurvnetFeature() { + firstName = faker.name().firstName(); + lastName = faker.name().lastName(); + + return Case.builder() + .dateOfReport(LocalDate.now()) + .responsibleRegion("Berlin") + .responsibleDistrict("SK Berlin Mitte") + .placeOfStay("EINRICHTUNG") + .facilityCategory("Medizinische Einrichtung") + .facilityType("Krankenhaus") + .facility("Andere Einrichtung") + .firstName(firstName) + .lastName(lastName) + .sex(GenderValues.getRandomGenderDE()) + .build(); + } + @SneakyThrows public Case buildCaseForSurvnetFeatureWithReinfection() { firstName = faker.name().firstName(); diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/HospitalizationService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/HospitalizationService.java index 55cb539976a..629d14c236c 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/HospitalizationService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/HospitalizationService.java @@ -1,6 +1,8 @@ package org.sormas.e2etests.entities.services; +import static org.sormas.e2etests.enums.ReasonForHospitalization.getRandomReasonForHospitalizationDE; import static org.sormas.e2etests.enums.YesNoUnknownOptions.YES; +import static org.sormas.e2etests.enums.YesNoUnknownOptionsDE.JA; import com.github.javafaker.Faker; import com.google.inject.Inject; @@ -32,4 +34,23 @@ public Hospitalization generateHospitalization() { .description("Additional description.") .build(); } + + public Hospitalization generateCurrentHospitalizationForDE() { + return Hospitalization.builder() + .wasPatientAdmittedAtTheFacilityAsAnInpatient(JA.toString()) + .dateOfVisitOrAdmission(LocalDate.now().minusDays(3)) + .dateOfDischargeOrTransfer(LocalDate.now().minusDays(1)) + .reasonForHospitalization(getRandomReasonForHospitalizationDE()) + .specifyReason("Exotic disease") + .stayInTheIntensiveCareUnit(JA.toString()) + .startOfStayDate(LocalDate.now().minusDays(2)) + .endOfStayDate(LocalDate.now().minusDays(1)) + .isolation(JA.toString()) + .dateOfIsolation(LocalDate.now().minusDays(6)) + .wasThePatientHospitalizedPreviously(JA.toString()) + .leftAgainstMedicalAdvice(JA.toString()) + .description("Additional description.") + .build(); + } + } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/PreviousHospitalizationService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/PreviousHospitalizationService.java index 0e0c6e282c5..da4ec280a98 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/PreviousHospitalizationService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/PreviousHospitalizationService.java @@ -1,6 +1,8 @@ package org.sormas.e2etests.entities.services; +import static org.sormas.e2etests.enums.ReasonForHospitalization.getRandomReasonForHospitalizationDE; import static org.sormas.e2etests.enums.YesNoUnknownOptions.YES; +import static org.sormas.e2etests.enums.YesNoUnknownOptionsDE.JA; import com.github.javafaker.Faker; import com.google.inject.Inject; @@ -38,4 +40,25 @@ public PreviousHospitalization generatePreviousHospitalization() { .wasPatientAdmittedAtTheFacilityAsAnInpatient(YES.toString()) .build(); } + + public PreviousHospitalization generatePreviousHospitalizationDE() { + return PreviousHospitalization.builder() + .dateOfVisitOrAdmission(LocalDate.now().minusDays(10)) + .dateOfDischargeOrTransfer(LocalDate.now().minusDays(5)) + .region("Berlin") + .district("SK Berlin Mitte") + .community("Gesundbrunnen") + .hospital("Andere Einrichtung") + .isolation(JA.toString()) + .dateOfIsolation(LocalDate.now().minusDays(8)) + .facilityNameDescription(faker.beer().name()) + .reasonForHospitalization(getRandomReasonForHospitalizationDE()) + .specifyReason(faker.book().title()) + .stayInTheIntensiveCareUnit(JA.toString()) + .startOfStayDate(LocalDate.now().minusDays(9)) + .endOfStayDate(LocalDate.now().minusDays(7)) + .description(faker.cat().breed() + " " + faker.color().name()) + .wasPatientAdmittedAtTheFacilityAsAnInpatient(JA.toString()) + .build(); + } } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CreateNewCaseSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CreateNewCaseSteps.java index d2334eb78c5..8d7a6f20168 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CreateNewCaseSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CreateNewCaseSteps.java @@ -1585,6 +1585,24 @@ public CreateNewCaseSteps( webDriverHelpers.clickOnWebElementBySelector(CASE_SAVED_POPUP); }); + And( + "^I create a new case with specific data using created facility for Survnet DE$", + () -> { + survnetCase = caseService.buildCaseWithFacilitiesForSurvnetFeature(); + fillDateOfReport(survnetCase.getDateOfReport(), Locale.GERMAN); + selectResponsibleRegion(survnetCase.getResponsibleRegion()); + selectResponsibleDistrict(survnetCase.getResponsibleDistrict()); + selectPlaceOfStay(survnetCase.getPlaceOfStay()); + selectFacilityCategory(survnetCase.getFacilityCategory()); + selectFacilityType(survnetCase.getFacilityType()); + selectFacility(survnetCase.getFacility()); + fillFirstName(survnetCase.getFirstName()); + fillLastName(survnetCase.getLastName()); + selectSex(survnetCase.getSex()); + webDriverHelpers.clickOnWebElementBySelector(SAVE_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(CASE_SAVED_POPUP); + }); + And( "^I create a new case with mandatory data only with Reinfection option for Survnet DE$", () -> { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/HospitalizationTabSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/HospitalizationTabSteps.java index cffbb8088e4..33bb5598d3c 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/HospitalizationTabSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/HospitalizationTabSteps.java @@ -27,6 +27,7 @@ public class HospitalizationTabSteps implements En { private final WebDriverHelpers webDriverHelpers; public static Hospitalization hospitalization; public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("M/d/yyyy"); + public static String reasonForCurrentHospitalization; @Inject public HospitalizationTabSteps( @@ -55,17 +56,16 @@ public HospitalizationTabSteps( "I complete all hospitalization fields and save", () -> { hospitalization = hospitalizationService.generateHospitalization(); - selectPatientAdmittedAtTheFacility( - hospitalization.getWasPatientAdmittedAtTheFacilityAsAnInpatient()); - fillDateOfVisitOrAdmission(hospitalization.getDateOfVisitOrAdmission()); + selectPatientAdmittedAtTheFacility(hospitalization.getWasPatientAdmittedAtTheFacilityAsAnInpatient()); + fillDateOfVisitOrAdmission(hospitalization.getDateOfVisitOrAdmission(), Locale.ENGLISH); selectReasonForHospitalization(hospitalization.getReasonForHospitalization()); - fillDateOfDischargeOrTransfer(hospitalization.getDateOfDischargeOrTransfer()); + fillDateOfDischargeOrTransfer(hospitalization.getDateOfDischargeOrTransfer(), Locale.ENGLISH); selectStayInTheIntensiveCareUnit(hospitalization.getStayInTheIntensiveCareUnit()); - fillStartOfStayDate(hospitalization.getStartOfStayDate()); - fillEndOfStayDate(hospitalization.getEndOfStayDate()); + fillStartOfStayDate(hospitalization.getStartOfStayDate(), Locale.ENGLISH); + fillEndOfStayDate(hospitalization.getEndOfStayDate(), Locale.ENGLISH); fillSpecifyReason(hospitalization.getSpecifyReason()); selectIsolation(hospitalization.getIsolation()); - fillDateOfIsolation(hospitalization.getDateOfIsolation()); + fillDateOfIsolation(hospitalization.getDateOfIsolation(), Locale.ENGLISH); selectWasThePatientHospitalizedPreviously( hospitalization.getWasThePatientHospitalizedPreviously()); selectLeftAgainstMedicalAdvice(hospitalization.getLeftAgainstMedicalAdvice()); @@ -75,6 +75,32 @@ public HospitalizationTabSteps( webDriverHelpers.waitUntilIdentifiedElementIsVisibleAndClickable(SUCCESSFUL_SAVE_POPUP); }); + When( + "I complete all hospitalization fields for Current Hospitalization and save it for DE", + () -> { + hospitalization = hospitalizationService.generateCurrentHospitalizationForDE(); + selectPatientAdmittedAtTheFacility( + hospitalization.getWasPatientAdmittedAtTheFacilityAsAnInpatient()); + fillDateOfVisitOrAdmission(hospitalization.getDateOfVisitOrAdmission(), Locale.GERMAN); + fillDateOfDischargeOrTransfer( + hospitalization.getDateOfDischargeOrTransfer(), Locale.GERMAN); + reasonForCurrentHospitalization = hospitalization.getReasonForHospitalization(); + selectReasonForHospitalization(reasonForCurrentHospitalization); + selectStayInTheIntensiveCareUnit(hospitalization.getStayInTheIntensiveCareUnit()); + fillStartOfStayDate(hospitalization.getStartOfStayDate(), Locale.GERMAN); + fillEndOfStayDate(hospitalization.getEndOfStayDate(), Locale.GERMAN); + selectWasThePatientHospitalizedPreviously( + hospitalization.getWasThePatientHospitalizedPreviously()); + fillSpecifyReason(hospitalization.getSpecifyReason()); + selectIsolation(hospitalization.getIsolation()); + fillDateOfIsolation(hospitalization.getDateOfIsolation(), Locale.GERMAN); + selectLeftAgainstMedicalAdvice(hospitalization.getLeftAgainstMedicalAdvice()); + fillDescription(hospitalization.getDescription()); + webDriverHelpers.clickOnWebElementBySelector(SAVE_BUTTON); + webDriverHelpers.waitUntilIdentifiedElementIsVisibleAndClickable(SUCCESSFUL_SAVE_POPUP); + TimeUnit.SECONDS.sleep(6); + }); + When( "I check the edited and saved data is correctly displayed on Hospitalization tab page", () -> { @@ -93,7 +119,7 @@ public HospitalizationTabSteps( When( "I set specific Date of visit or admission", () -> { - fillDateOfVisitOrAdmission(LocalDate.now().minusDays(1)); + fillDateOfVisitOrAdmission(LocalDate.now().minusDays(1), Locale.ENGLISH); }); When( @@ -184,14 +210,18 @@ private void selectPatientAdmittedAtTheFacility(String yesNoUnknown) { TimeUnit.SECONDS.sleep(1); } - private void fillDateOfVisitOrAdmission(LocalDate date) { - webDriverHelpers.fillInWebElement( - DATE_OF_VISIT_OR_ADMISSION_INPUT, DATE_FORMATTER.format(date)); + private void fillDateOfVisitOrAdmission(LocalDate date, Locale locale) { + DateTimeFormatter formatter; + if (locale.equals(Locale.GERMAN)) formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); + else formatter = DateTimeFormatter.ofPattern("M/d/yyyy"); + webDriverHelpers.fillInWebElement(DATE_OF_VISIT_OR_ADMISSION_INPUT, formatter.format(date)); } - private void fillDateOfDischargeOrTransfer(LocalDate date) { - webDriverHelpers.fillInWebElement( - DATE_OF_DISCHARGE_OR_TRANSFER_INPUT, DATE_FORMATTER.format(date)); + private void fillDateOfDischargeOrTransfer(LocalDate date, Locale locale) { + DateTimeFormatter formatter; + if (locale.equals(Locale.GERMAN)) formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); + else formatter = DateTimeFormatter.ofPattern("M/d/yyyy"); + webDriverHelpers.fillInWebElement(DATE_OF_DISCHARGE_OR_TRANSFER_INPUT, formatter.format(date)); } private void selectReasonForHospitalization(String reason) { @@ -206,21 +236,29 @@ private void selectStayInTheIntensiveCareUnit(String option) { webDriverHelpers.clickWebElementByText(STAY_IN_THE_INTENSIVE_CARE_UNIT_OPTIONS, option); } - private void fillStartOfStayDate(LocalDate date) { - webDriverHelpers.fillInWebElement(START_OF_STAY_DATE_INPUT, DATE_FORMATTER.format(date)); + private void fillStartOfStayDate(LocalDate date, Locale locale) { + DateTimeFormatter formatter; + if (locale.equals(Locale.GERMAN)) formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); + else formatter = DateTimeFormatter.ofPattern("M/d/yyyy"); + webDriverHelpers.fillInWebElement(START_OF_STAY_DATE_INPUT, formatter.format(date)); } - private void fillEndOfStayDate(LocalDate date) { - webDriverHelpers.clickOnWebElementBySelector(END_OF_STAY_DATE_INPUT); - webDriverHelpers.fillInWebElement(END_OF_STAY_DATE_INPUT, DATE_FORMATTER.format(date)); + private void fillEndOfStayDate(LocalDate date, Locale locale) { + DateTimeFormatter formatter; + if (locale.equals(Locale.GERMAN)) formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); + else formatter = DateTimeFormatter.ofPattern("M/d/yyyy"); + webDriverHelpers.fillInWebElement(END_OF_STAY_DATE_INPUT, formatter.format(date)); } private void selectIsolation(String option) { webDriverHelpers.clickWebElementByText(ISOLATION_OPTIONS, option); } - private void fillDateOfIsolation(LocalDate date) { - webDriverHelpers.fillInWebElement(DATE_OF_ISOLATION_INPUT, DATE_FORMATTER.format(date)); + private void fillDateOfIsolation(LocalDate date, Locale locale) { + DateTimeFormatter formatter; + if (locale.equals(Locale.GERMAN)) formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); + else formatter = DateTimeFormatter.ofPattern("M/d/yyyy"); + webDriverHelpers.fillInWebElement(DATE_OF_ISOLATION_INPUT, formatter.format(date)); } private void selectWasThePatientHospitalizedPreviously(String option) { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/PreviousHospitalizationSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/PreviousHospitalizationSteps.java index ee128516565..225c05b7bef 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/PreviousHospitalizationSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/PreviousHospitalizationSteps.java @@ -1,12 +1,23 @@ package org.sormas.e2etests.steps.web.application.cases; -import static org.sormas.e2etests.pages.application.cases.HospitalizationTabPage.FIRST_PREVIOUS_HOSPITALIZATION_ENTRY; -import static org.sormas.e2etests.pages.application.cases.HospitalizationTabPage.NEW_ENTRY_LINK; +import static org.sormas.e2etests.enums.YesNoUnknownOptionsDE.JA; +import static org.sormas.e2etests.pages.application.cases.HospitalizationTabPage.*; import static org.sormas.e2etests.pages.application.cases.PreviousHospitalizationPage.*; +import static org.sormas.e2etests.pages.application.cases.PreviousHospitalizationPage.DATE_OF_DISCHARGE_OR_TRANSFER_INPUT; +import static org.sormas.e2etests.pages.application.cases.PreviousHospitalizationPage.DATE_OF_VISIT_OR_ADMISSION_INPUT; +import static org.sormas.e2etests.pages.application.cases.PreviousHospitalizationPage.DESCRIPTION_INPUT; +import static org.sormas.e2etests.pages.application.cases.PreviousHospitalizationPage.END_OF_STAY_DATE_INPUT; +import static org.sormas.e2etests.pages.application.cases.PreviousHospitalizationPage.ISOLATION_OPTIONS; +import static org.sormas.e2etests.pages.application.cases.PreviousHospitalizationPage.REASON_FOR_HOSPITALIZATION_COMBOBOX; +import static org.sormas.e2etests.pages.application.cases.PreviousHospitalizationPage.SPECIFY_REASON_INPUT; +import static org.sormas.e2etests.pages.application.cases.PreviousHospitalizationPage.START_OF_STAY_DATE_INPUT; +import static org.sormas.e2etests.pages.application.cases.PreviousHospitalizationPage.STAY_IN_THE_INTENSIVE_CARE_UNIT_OPTIONS; +import static org.sormas.e2etests.steps.BaseSteps.locale; import cucumber.api.java8.En; import java.time.LocalDate; import java.time.format.DateTimeFormatter; +import java.util.Locale; import javax.inject.Inject; import org.sormas.e2etests.entities.pojo.helpers.ComparisonHelper; import org.sormas.e2etests.entities.pojo.web.Hospitalization; @@ -21,6 +32,7 @@ public class PreviousHospitalizationSteps implements En { public static PreviousHospitalization previousHospitalization; private static Hospitalization createdHospitalization; public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("M/d/yyyy"); + public static String reasonForPreviousHospitalization; @Inject public PreviousHospitalizationSteps( @@ -37,25 +49,58 @@ public PreviousHospitalizationSteps( webDriverHelpers.clickOnWebElementBySelector(NEW_ENTRY_LINK); previousHospitalization = previousHospitalizationService.generatePreviousHospitalization(); - fillDateOfVisitOrAdmission(previousHospitalization.getDateOfVisitOrAdmission()); + fillDateOfVisitOrAdmission(previousHospitalization.getDateOfVisitOrAdmission(), Locale.ENGLISH); selectReasonForHospitalization(previousHospitalization.getReasonForHospitalization()); - fillDateOfDischargeOrTransfer(previousHospitalization.getDateOfDischargeOrTransfer()); + fillDateOfDischargeOrTransfer(previousHospitalization.getDateOfDischargeOrTransfer(), Locale.ENGLISH); selectStayInTheIntensiveCareUnit(previousHospitalization.getStayInTheIntensiveCareUnit()); selectRegion(previousHospitalization.getRegion()); selectDistrict(previousHospitalization.getDistrict()); selectCommunity(previousHospitalization.getCommunity()); selectHospital(previousHospitalization.getHospital()); - fillStartOfStayDate(previousHospitalization.getStartOfStayDate()); + fillStartOfStayDate(previousHospitalization.getStartOfStayDate(), Locale.ENGLISH); selectIsolation(previousHospitalization.getIsolation()); - fillDateOfIsolation(previousHospitalization.getDateOfIsolation()); - fillEndOfStayDate(previousHospitalization.getEndOfStayDate()); + fillDateOfIsolation(previousHospitalization.getDateOfIsolation(), Locale.ENGLISH); + fillEndOfStayDate(previousHospitalization.getEndOfStayDate(), Locale.ENGLISH); fillSpecifyReason(previousHospitalization.getSpecifyReason()); fillDescription(previousHospitalization.getDescription()); fillFacilityNameDescription(previousHospitalization.getFacilityNameDescription()); + selectWasPatientAdmittedAtTheFacilityAsAnInpatient(previousHospitalization.getIsolation()); + webDriverHelpers.clickOnWebElementBySelector(DONE_BUTTON); + webDriverHelpers.waitUntilIdentifiedElementIsVisibleAndClickable(NEW_ENTRY_LINK); + }); + + When( + "I add a previous hospitalization and save for DE", + () -> { + webDriverHelpers.clickWebElementByText( + WAS_THE_PATIENT_HOSPITALIZED_PREVIOUSLY_OPTIONS, JA.toString()); + webDriverHelpers.clickOnWebElementBySelector(NEW_ENTRY_LINK); + previousHospitalization = + previousHospitalizationService.generatePreviousHospitalizationDE(); + fillDateOfVisitOrAdmission( + previousHospitalization.getDateOfVisitOrAdmission(), Locale.GERMAN); + reasonForPreviousHospitalization = previousHospitalization.getReasonForHospitalization(); + selectReasonForHospitalization(reasonForPreviousHospitalization); + fillDateOfDischargeOrTransfer( + previousHospitalization.getDateOfDischargeOrTransfer(), Locale.GERMAN); + selectStayInTheIntensiveCareUnit(previousHospitalization.getStayInTheIntensiveCareUnit()); + selectRegion(previousHospitalization.getRegion()); + selectDistrict(previousHospitalization.getDistrict()); + selectCommunity(previousHospitalization.getCommunity()); + selectHospital(previousHospitalization.getHospital()); + fillFacilityNameDescription(previousHospitalization.getFacilityNameDescription()); + fillStartOfStayDate(previousHospitalization.getStartOfStayDate(), Locale.GERMAN); + selectIsolation(previousHospitalization.getIsolation()); + fillDateOfIsolation(previousHospitalization.getDateOfIsolation(), Locale.GERMAN); + fillEndOfStayDate(previousHospitalization.getEndOfStayDate(), Locale.GERMAN); + fillDescription(previousHospitalization.getDescription()); selectWasPatientAdmittedAtTheFacilityAsAnInpatient( previousHospitalization.getIsolation()); webDriverHelpers.clickOnWebElementBySelector(DONE_BUTTON); webDriverHelpers.waitUntilIdentifiedElementIsVisibleAndClickable(NEW_ENTRY_LINK); + + webDriverHelpers.clickOnWebElementBySelector(SAVE_BUTTON); + webDriverHelpers.waitUntilIdentifiedElementIsVisibleAndClickable(SUCCESSFUL_SAVE_POPUP); }); When( @@ -146,14 +191,18 @@ public PreviousHospitalizationSteps( }); } - private void fillDateOfVisitOrAdmission(LocalDate date) { - webDriverHelpers.fillInWebElement( - DATE_OF_VISIT_OR_ADMISSION_INPUT, DATE_FORMATTER.format(date)); + private void fillDateOfVisitOrAdmission(LocalDate date, Locale locale) { + DateTimeFormatter formatter; + if (locale.equals(Locale.GERMAN)) formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); + else formatter = DateTimeFormatter.ofPattern("M/d/yyyy"); + webDriverHelpers.fillInWebElement(DATE_OF_VISIT_OR_ADMISSION_INPUT, formatter.format(date)); } - private void fillDateOfDischargeOrTransfer(LocalDate date) { - webDriverHelpers.fillInWebElement( - DATE_OF_DISCHARGE_OR_TRANSFER_INPUT, DATE_FORMATTER.format(date)); + private void fillDateOfDischargeOrTransfer(LocalDate date, Locale locale) { + DateTimeFormatter formatter; + if (locale.equals(Locale.GERMAN)) formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); + else formatter = DateTimeFormatter.ofPattern("M/d/yyyy"); + webDriverHelpers.fillInWebElement(DATE_OF_DISCHARGE_OR_TRANSFER_INPUT, formatter.format(date)); } private void selectReasonForHospitalization(String reason) { @@ -168,20 +217,29 @@ private void selectStayInTheIntensiveCareUnit(String option) { webDriverHelpers.clickWebElementByText(STAY_IN_THE_INTENSIVE_CARE_UNIT_OPTIONS, option); } - private void fillStartOfStayDate(LocalDate date) { - webDriverHelpers.fillInWebElement(START_OF_STAY_DATE_INPUT, DATE_FORMATTER.format(date)); + private void fillStartOfStayDate(LocalDate date, Locale locale) { + DateTimeFormatter formatter; + if (locale.equals(Locale.GERMAN)) formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); + else formatter = DateTimeFormatter.ofPattern("M/d/yyyy"); + webDriverHelpers.fillInWebElement(START_OF_STAY_DATE_INPUT, formatter.format(date)); } - private void fillEndOfStayDate(LocalDate date) { - webDriverHelpers.fillInWebElement(END_OF_STAY_DATE_INPUT, DATE_FORMATTER.format(date)); + private void fillEndOfStayDate(LocalDate date, Locale locale) { + DateTimeFormatter formatter; + if (locale.equals(Locale.GERMAN)) formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); + else formatter = DateTimeFormatter.ofPattern("M/d/yyyy"); + webDriverHelpers.fillInWebElement(END_OF_STAY_DATE_INPUT, formatter.format(date)); } private void selectIsolation(String option) { webDriverHelpers.clickWebElementByText(ISOLATION_OPTIONS, option); } - private void fillDateOfIsolation(LocalDate date) { - webDriverHelpers.fillInWebElement(DATE_OF_ISOLATION, DATE_FORMATTER.format(date)); + private void fillDateOfIsolation(LocalDate date, Locale locale) { + DateTimeFormatter formatter; + if (locale.equals(Locale.GERMAN)) formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); + else formatter = DateTimeFormatter.ofPattern("M/d/yyyy"); + webDriverHelpers.fillInWebElement(DATE_OF_ISOLATION, formatter.format(date)); } private void selectRegion(String option) { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java index c665e9f7cbe..4f71b6281d8 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java @@ -15,6 +15,9 @@ import static org.sormas.e2etests.steps.web.application.cases.CaseReinfectionSteps.TheLastPositivePCRDetectionWasMoreThan3MonthsAgo; import static org.sormas.e2etests.steps.web.application.cases.CreateNewCaseSteps.survnetCase; import static org.sormas.e2etests.steps.web.application.cases.EditCaseSteps.externalUUID; +import static org.sormas.e2etests.steps.web.application.cases.HospitalizationTabSteps.*; +import static org.sormas.e2etests.steps.web.application.cases.PreviousHospitalizationSteps.previousHospitalization; +import static org.sormas.e2etests.steps.web.application.cases.PreviousHospitalizationSteps.reasonForPreviousHospitalization; import static org.sormas.e2etests.steps.web.application.cases.SymptomsTabSteps.symptoms; import static org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps.randomVaccinationName; import static org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps.vaccination; @@ -90,6 +93,86 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { } }); + Then( + "I check if {string} for Current Hospitalization in SORMAS generated XML file is correct", + (String typeOfDate) -> { + switch (typeOfDate) { + case "date of visit or admission": + LocalDate expectedStayFromDate = hospitalization.getDateOfVisitOrAdmission(); + softly.assertEquals( + getValueFromLowChildrenDateSpecificFieldByName(singleXmlFile, "StayFrom"), + expectedStayFromDate, + "Date of visit or admission is incorrect!"); + softly.assertAll(); + break; + case "date of discharge or transfer": + LocalDate expectedStayUntilDate = + hospitalization.getDateOfDischargeOrTransfer(); + softly.assertEquals( + getValueFromLowChildrenDateSpecificFieldByName(singleXmlFile, "StayUntil"), + expectedStayUntilDate, + "Date of discharge or transfer is incorrect!"); + softly.assertAll(); + break; + case "start of the stay": + LocalDate expectedStartOfTheStay = hospitalization.getStartOfStayDate(); + softly.assertEquals( + getValueFromLowChildrenDateSpecificFieldByName(singleXmlFile, "ITSStayFrom"), + expectedStartOfTheStay, + "Start of the stay date is incorrect!"); + softly.assertAll(); + break; + case "end of the stay": + LocalDate expectedEndOfTheStay = hospitalization.getEndOfStayDate(); + softly.assertEquals( + getValueFromLowChildrenDateSpecificFieldByName(singleXmlFile, "ITSStayUntil"), + expectedEndOfTheStay, + "End of the stay date is incorrect!"); + softly.assertAll(); + break; + } + }); + + Then( + "I check if {string} for Previous Hospitalization in SORMAS generated XML file is correct", + (String typeOfDate) -> { + switch (typeOfDate) { + case "date of visit or admission": + LocalDate expectedStayFromDate = previousHospitalization.getDateOfVisitOrAdmission(); + softly.assertEquals( + getValueFromLowChildrenDateSpecificFieldByName(singleXmlFile, "StayFrom"), + expectedStayFromDate, + "Date of visit or admission is incorrect!"); + softly.assertAll(); + break; + case "date of discharge or transfer": + LocalDate expectedStayUntilDate = + previousHospitalization.getDateOfDischargeOrTransfer(); + softly.assertEquals( + getValueFromLowChildrenDateSpecificFieldByName(singleXmlFile, "StayUntil"), + expectedStayUntilDate, + "Date of discharge or transfer is incorrect!"); + softly.assertAll(); + break; + case "start of the stay": + LocalDate expectedStartOfTheStay = previousHospitalization.getStartOfStayDate(); + softly.assertEquals( + getValueFromLowChildrenDateSpecificFieldByName(singleXmlFile, "ITSStayFrom"), + expectedStartOfTheStay, + "Start of the stay date is incorrect!"); + softly.assertAll(); + break; + case "end of the stay": + LocalDate expectedEndOfTheStay = previousHospitalization.getEndOfStayDate(); + softly.assertEquals( + getValueFromLowChildrenDateSpecificFieldByName(singleXmlFile, "ITSStayUntil"), + expectedEndOfTheStay, + "End of the stay date is incorrect!"); + softly.assertAll(); + break; + } + }); + Then( "I check if Vaccine name in SORMAS generated XML file is correct", () -> { @@ -139,6 +222,58 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { softly.assertAll(); }); + And( + "I check reason for Current Hospitalization in SORMAS generated single XML file is correct", + () -> { + String expectedReasonForHospitalizationValue = null; + switch (reasonForCurrentHospitalization) { + case "Anderer Grund": + expectedReasonForHospitalizationValue = "2"; + break; + case "Gemeldete Krankheit": + expectedReasonForHospitalizationValue = "1"; + break; + case "Isolation": + expectedReasonForHospitalizationValue = "4"; + break; + case "Unbekannt": + expectedReasonForHospitalizationValue = "3"; + break; + } + + softly.assertEquals( + getValueFromLowChildrenSpecificFieldByName(singleXmlFile, "Reason"), + expectedReasonForHospitalizationValue, + "Reason is incorrect!"); + softly.assertAll(); + }); + + And( + "I check reason for Previous Hospitalization in SORMAS generated single XML file is correct", + () -> { + String expectedReasonForHospitalizationValue = null; + switch (reasonForPreviousHospitalization) { + case "Anderer Grund": + expectedReasonForHospitalizationValue = "2"; + break; + case "Gemeldete Krankheit": + expectedReasonForHospitalizationValue = "1"; + break; + case "Isolation": + expectedReasonForHospitalizationValue = "4"; + break; + case "Unbekannt": + expectedReasonForHospitalizationValue = "3"; + break; + } + + softly.assertEquals( + getValueFromLowChildrenSpecificFieldByName(singleXmlFile, "Reason"), + expectedReasonForHospitalizationValue, + "Reason is incorrect!"); + softly.assertAll(); + }); + And( "I check if Reinfection option is set in SORMAS generated single XML file is correct", () -> { @@ -599,6 +734,41 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { softly.assertAll(); }); + And( + "^I check if Stay in the intensive care unit value Current Hospitalization in SORMAS generated XML file is correct$", + () -> { + String expectedStayInTheIntensiveCareValue; + String StayInTheIntensiveCareValueUI = hospitalization.getStayInTheIntensiveCareUnit(); + + if (StayInTheIntensiveCareValueUI.equals("JA")) + expectedStayInTheIntensiveCareValue = "true"; + else expectedStayInTheIntensiveCareValue = "false"; + + softly.assertEquals( + getValueFromLowChildrenSpecificFieldByName(singleXmlFile, "Intensivstation"), + expectedStayInTheIntensiveCareValue, + "Stay in the intensive care unit value is incorrect!"); + softly.assertAll(); + }); + + And( + "^I check if Stay in the intensive care unit value for Previous Hospitalization in SORMAS generated XML file is correct$", + () -> { + String expectedStayInTheIntensiveCareValue; + String StayInTheIntensiveCareValueUI = + previousHospitalization.getStayInTheIntensiveCareUnit(); + + if (StayInTheIntensiveCareValueUI.equals("JA")) + expectedStayInTheIntensiveCareValue = "true"; + else expectedStayInTheIntensiveCareValue = "false"; + + softly.assertEquals( + getValueFromLowChildrenSpecificFieldByName(singleXmlFile, "Intensivstation"), + expectedStayInTheIntensiveCareValue, + "Stay in the intensive care unit value is incorrect!"); + softly.assertAll(); + }); + And( "^I open SORMAS generated XML file for single case message$", () -> { @@ -777,6 +947,89 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { } }); + And( + "^I check if Previous Hospitalization Was Patient Admitted has correct value mapped in SORMAS generated single XML file$$", + () -> { + String wasPatientHospitalized = + previousHospitalization.getWasPatientAdmittedAtTheFacilityAsAnInpatient(); + String StatusHospitalizationValue = null; + switch (wasPatientHospitalized) { + case "JA": + StatusHospitalizationValue = "20"; + break; + case "NEIN": + StatusHospitalizationValue = "0"; + break; + case "UNBEKANNT": + StatusHospitalizationValue = "-1"; + break; + } + + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "StatusHospitalization"), + StatusHospitalizationValue, + "Status Hospital value for Current Hospitalization Was Patient Admitted is incorrect"); + softly.assertAll(); + }); + + And( + "^I check if Current Hospitalization Was Patient Admitted has correct value mapped in SORMAS generated single XML file$$", + () -> { + String wasPatientHospitalized = survnetCase.getResponsibleRegion(); + String StatusHospitalizationValue = null; + switch (wasPatientHospitalized) { + case "JA": + StatusHospitalizationValue = "20"; + break; + case "NEIN": + StatusHospitalizationValue = "0"; + break; + case "UNBEKANNT": + StatusHospitalizationValue = "-1"; + break; + } + + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "StatusHospitalization"), + StatusHospitalizationValue, + "Status Hospital value for Current Hospitalization Was Patient Admitted is incorrect"); + softly.assertAll(); + }); + + And( + "^I check if Region from Previous Hospitalization value in SORMAS generated XML file is correct$", + () -> { + String regionUI = previousHospitalization.getRegion(); + String expectedRegionUUID = null; + switch (regionUI) { + case "Berlin": + expectedRegionUUID = "11011001"; + break; + } + softly.assertEquals( + getValueFromLowChildrenSpecificFieldByName(singleXmlFile, "Region"), + expectedRegionUUID, + "Region UUID is incorrect!"); + softly.assertAll(); + }); + + And( + "^I check if Region from Current Hospitalization value in SORMAS generated XML file is correct$", + () -> { + String regionUI = survnetCase.getResponsibleRegion(); + String expectedRegionUUID = null; + switch (regionUI) { + case "Berlin": + expectedRegionUUID = "11011001"; + break; + } + softly.assertEquals( + getValueFromLowChildrenSpecificFieldByName(singleXmlFile, "Region"), + expectedRegionUUID, + "Region UUID is incorrect!"); + softly.assertAll(); + }); + Then( "^I check if the infection setting \"([^\"]*)\" is correctly mapped in SORMAS generated single XML file$", (String infectionOption) -> { @@ -945,6 +1198,60 @@ private String getValueFromSpecificFieldByName(Document xmlFile, String name) { return value; } + private String getValueFromLowChildrenSpecificFieldByName(Document xmlFile, String name) { + Element rootElement = xmlFile.getRootElement(); + Namespace ns = rootElement.getNamespace(); + String value = null; + + Element field = + xmlFile + .getRootElement() + .getChildren() + .get(0) + .getChildren("Group", ns) + .get(0) + .getChildren("Field", ns) + .stream() + .filter(e -> e.getAttributeValue("Name").equals(name)) + .findFirst() + .orElse(null); + + if (field != null) { + Attribute valueAttribute = field.getAttribute("Value"); + if (valueAttribute != null) { + value = valueAttribute.getValue(); + } + } + return value; + } + + private LocalDate getValueFromLowChildrenDateSpecificFieldByName(Document xmlFile, String name) { + Element rootElement = xmlFile.getRootElement(); + Namespace ns = rootElement.getNamespace(); + String value = null; + + Element field = + xmlFile + .getRootElement() + .getChildren() + .get(0) + .getChildren("Group", ns) + .get(0) + .getChildren("Field", ns) + .stream() + .filter(e -> e.getAttributeValue("Name").equals(name)) + .findFirst() + .orElse(null); + + if (field != null) { + Attribute valueAttribute = field.getAttribute("Value"); + if (valueAttribute != null) { + value = valueAttribute.getValue().substring(0, 10); + } + } + return LocalDate.parse(value, DATE_FORMATTER); + } + private LocalDate getDateValueFromSpecificChildNodeFieldByName(Document xmlFile, String name) { Element rootElement = xmlFile.getRootElement(); Namespace ns = rootElement.getNamespace(); diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature index 171b7513d65..2771ea9bbb1 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature @@ -370,4 +370,48 @@ Feature: Survnet tests And I click on save case button And I click on De-Archive case button And I fill De-Archive case popup with test automation reason - And I validate the existence of "5" Reporting Tools entries in Survnet box \ No newline at end of file + And I validate the existence of "5" Reporting Tools entries in Survnet box + + @tmsLink=SORQA-1051 + Scenario: Check Current Hospitalization of case when sending from SORMAS to Meldesoftware + Given I log in as a Survnet + When I click on the Cases button from navbar + And I click on the NEW CASE button + Then I create a new case with specific data using created facility for Survnet DE + And I navigate to Hospitalization tab in Cases + Then I complete all hospitalization fields for Current Hospitalization and save it for DE + And I navigate to case tab + And I click on Send to reporting tool button on Edit Case page + And I collect case external UUID from Edit Case page + Then I wait 50 seconds for system reaction + And I open SORMAS generated XML file for single case message + And I check if Current Hospitalization Was Patient Admitted has correct value mapped in SORMAS generated single XML file + And I check if Region from Current Hospitalization value in SORMAS generated XML file is correct + Then I check if "date of visit or admission" for Current Hospitalization in SORMAS generated XML file is correct + Then I check if "date of discharge or transfer" for Current Hospitalization in SORMAS generated XML file is correct + And I check reason for Current Hospitalization in SORMAS generated single XML file is correct + And I check if Stay in the intensive care unit value Current Hospitalization in SORMAS generated XML file is correct + Then I check if "start of the stay" for Current Hospitalization in SORMAS generated XML file is correct + Then I check if "end of the stay" for Current Hospitalization in SORMAS generated XML file is correct + + @tmsLink=SORQA-1051 + Scenario: Check Previous Hospitalization of case when sending from SORMAS to Meldesoftware + Given I log in as a Survnet + When I click on the Cases button from navbar + And I click on the NEW CASE button + Then I create a new case with specific data using created facility for Survnet DE + And I navigate to Hospitalization tab in Cases + Then I add a previous hospitalization and save for DE + And I navigate to case tab + And I click on Send to reporting tool button on Edit Case page + And I collect case external UUID from Edit Case page + Then I wait 50 seconds for system reaction + And I open SORMAS generated XML file for single case message + And I check if Previous Hospitalization Was Patient Admitted has correct value mapped in SORMAS generated single XML file + And I check if Region from Previous Hospitalization value in SORMAS generated XML file is correct + And I check if "date of visit or admission" for Previous Hospitalization in SORMAS generated XML file is correct + And I check if "date of discharge or transfer" for Previous Hospitalization in SORMAS generated XML file is correct + Then I check reason for Previous Hospitalization in SORMAS generated single XML file is correct + And I check if Stay in the intensive care unit value for Previous Hospitalization in SORMAS generated XML file is correct + And I check if "start of the stay" for Previous Hospitalization in SORMAS generated XML file is correct + And I check if "end of the stay" for Previous Hospitalization in SORMAS generated XML file is correct \ No newline at end of file From 1366058786bbfab09500456e5fd59107938a3cae Mon Sep 17 00:00:00 2001 From: Michal Kozakiewicz Date: Mon, 7 Aug 2023 12:45:27 +0200 Subject: [PATCH 167/174] SORQA-1051 Implement "Check Hospitalization of case when sending from SORMAS to Meldesoftware" - changed variable that caused a failure --- .../e2etests/steps/web/application/survnet/SurvNetSteps.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java index 4f71b6281d8..3a2cc7cbf92 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java @@ -975,7 +975,7 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { And( "^I check if Current Hospitalization Was Patient Admitted has correct value mapped in SORMAS generated single XML file$$", () -> { - String wasPatientHospitalized = survnetCase.getResponsibleRegion(); + String wasPatientHospitalized = hospitalization.getWasPatientAdmittedAtTheFacilityAsAnInpatient(); String StatusHospitalizationValue = null; switch (wasPatientHospitalized) { case "JA": From 566a2acb34a1fa6959a511da84780590c5cb24d7 Mon Sep 17 00:00:00 2001 From: hms-sgent Date: Mon, 7 Aug 2023 13:25:04 +0200 Subject: [PATCH 168/174] qu-auto/SORQA-1024 Demis - Process a Physician Report. New test steps have been added. --- .../web/application/survnet/SurvNetSteps.java | 58 +++++++++++-------- .../features/sanity/web/Survnet.feature | 21 ++++++- 2 files changed, 53 insertions(+), 26 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java index c665e9f7cbe..0debc13493c 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/survnet/SurvNetSteps.java @@ -1,31 +1,6 @@ package org.sormas.e2etests.steps.web.application.survnet; -import static org.sormas.e2etests.helpers.SchemaValidator.XMLSchemaValidator.validateXMLSchema; -import static org.sormas.e2etests.helpers.comparison.XMLComparison.compareXMLFiles; -import static org.sormas.e2etests.helpers.comparison.XMLComparison.extractDiffNodes; -import static org.sormas.e2etests.pages.application.AboutPage.SORMAS_VERSION_LINK; -import static org.sormas.e2etests.steps.web.application.cases.CaseReinfectionSteps.CovidGenomeCopyNumber; -import static org.sormas.e2etests.steps.web.application.cases.CaseReinfectionSteps.CurrentCovidInfectionDoNotMatchValue; -import static org.sormas.e2etests.steps.web.application.cases.CaseReinfectionSteps.CurrentCovidInfectionIsKnownValue; -import static org.sormas.e2etests.steps.web.application.cases.CaseReinfectionSteps.IndividualTestedPositiveForCovidByPCR; -import static org.sormas.e2etests.steps.web.application.cases.CaseReinfectionSteps.PersonHadAnAsymptomaticCovidInfection; -import static org.sormas.e2etests.steps.web.application.cases.CaseReinfectionSteps.PersonHasOvercomeAcuteRespiratory; -import static org.sormas.e2etests.steps.web.application.cases.CaseReinfectionSteps.PersonTestedConclusivelyNegativeByPCR; -import static org.sormas.e2etests.steps.web.application.cases.CaseReinfectionSteps.PreviousCovidInfectionIsKnownValue; -import static org.sormas.e2etests.steps.web.application.cases.CaseReinfectionSteps.TheLastPositivePCRDetectionWasMoreThan3MonthsAgo; -import static org.sormas.e2etests.steps.web.application.cases.CreateNewCaseSteps.survnetCase; -import static org.sormas.e2etests.steps.web.application.cases.EditCaseSteps.externalUUID; -import static org.sormas.e2etests.steps.web.application.cases.SymptomsTabSteps.symptoms; -import static org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps.randomVaccinationName; -import static org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps.vaccination; - import cucumber.api.java8.En; -import java.time.LocalDate; -import java.time.Period; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.List; -import javax.inject.Inject; import lombok.extern.slf4j.Slf4j; import org.jdom2.Attribute; import org.jdom2.DataConversionException; @@ -40,6 +15,24 @@ import org.sormas.e2etests.steps.web.application.persons.EditPersonSteps; import org.testng.asserts.SoftAssert; +import javax.inject.Inject; +import java.time.LocalDate; +import java.time.Period; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +import static org.sormas.e2etests.helpers.SchemaValidator.XMLSchemaValidator.validateXMLSchema; +import static org.sormas.e2etests.helpers.comparison.XMLComparison.compareXMLFiles; +import static org.sormas.e2etests.helpers.comparison.XMLComparison.extractDiffNodes; +import static org.sormas.e2etests.pages.application.AboutPage.SORMAS_VERSION_LINK; +import static org.sormas.e2etests.steps.web.application.cases.CaseReinfectionSteps.*; +import static org.sormas.e2etests.steps.web.application.cases.CreateNewCaseSteps.survnetCase; +import static org.sormas.e2etests.steps.web.application.cases.EditCaseSteps.externalUUID; +import static org.sormas.e2etests.steps.web.application.cases.SymptomsTabSteps.symptoms; +import static org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps.randomVaccinationName; +import static org.sormas.e2etests.steps.web.application.vaccination.CreateNewVaccinationSteps.vaccination; + @Slf4j public class SurvNetSteps implements En { @@ -797,6 +790,21 @@ public SurvNetSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { break; } }); + + Then( + "^I check if the exposure settings are correctly mapped in SORMAS generated single XML file$", + () -> { + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "StatusInfectionEnvironmentCVD"), + "-1", + "Status Infection Environment CVD is incorrect!"); + softly.assertAll(); + softly.assertEquals( + getValueFromSpecificFieldByName(singleXmlFile, "StatusPlaceOfInf"), + "20", + "Status Place Of Inf is incorrect!"); + softly.assertAll(); + }); } private LocalDate getReportingDate(Document xmlFile, int caseNumber) { diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature index 171b7513d65..e25d82286fc 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Survnet.feature @@ -370,4 +370,23 @@ Feature: Survnet tests And I click on save case button And I click on De-Archive case button And I fill De-Archive case popup with test automation reason - And I validate the existence of "5" Reporting Tools entries in Survnet box \ No newline at end of file + And I validate the existence of "5" Reporting Tools entries in Survnet box + + @tmsLink=SORQA-1052 + Scenario: Check Epidemiology data "Expositionsuntersuchung" of case when sending from SORMAS to Meldesoftware + Given I log in as a Survnet + When I click on the Cases button from navbar + And I click on the NEW CASE button + And I create a new case with mandatory data only for Survnet DE + And I navigate to epidemiological data tab in Edit case page + And I click on Exposure details known with JA option + And I click on New Entry in Exposure Details Known in Cases directory + And I select Reisen option in Type of activity from Combobox in Exposure form + And I click on save button in Exposure for Epidemiological data tab in Cases + And I click on save button from Epidemiological Data + And I navigate to case tab + And I click on Send to reporting tool button on Edit Case page + And I collect case external UUID from Edit Case page + Then I wait 50 seconds for system reaction + And I open SORMAS generated XML file for single case message + Then I check if the exposure settings are correctly mapped in SORMAS generated single XML file \ No newline at end of file From 314cf6b0f4f6101ab07aa5cec84cbc9218bd8cdb Mon Sep 17 00:00:00 2001 From: Michal Kozakiewicz Date: Mon, 7 Aug 2023 13:37:45 +0200 Subject: [PATCH 169/174] SORQA-1064 Stabilize "Re-send Case from SORMAS to Meldesoftware" - the format of date was changed --- .../e2etests/steps/web/application/cases/EditCaseSteps.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java index e309b670f01..385dc0e1fbc 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java @@ -1846,7 +1846,7 @@ public EditCaseSteps( softly.assertEquals( endOfProcessingDate, - LocalDate.now().format(DateTimeFormatter.ofPattern("d.MM.yyyy")), + LocalDate.now().format(DateTimeFormatter.ofPattern("dd.MM.yyyy")), "End of processing date is invalid"); softly.assertAll(); webDriverHelpers.clickOnWebElementBySelector(ARCHIVE_RELATED_CONTACTS_CHECKBOX); From cf896123a2ed6c68072c977f9d2c8c3345331b08 Mon Sep 17 00:00:00 2001 From: Michal Kozakiewicz Date: Mon, 7 Aug 2023 15:56:05 +0200 Subject: [PATCH 170/174] SORQA-1054 Stabilize "Testing Event screen Impact" - chenged NEW_GROUP_EVENT_CREATED_MESSAGE and handle a popup created message --- .../e2etests/pages/application/events/EditEventPage.java | 3 ++- .../e2etests/steps/web/application/events/EditEventSteps.java | 3 +++ .../src/test/resources/features/sanity/web/Event.feature | 3 +-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/events/EditEventPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/events/EditEventPage.java index d13cf276079..bc42cdd7d55 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/events/EditEventPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/events/EditEventPage.java @@ -70,7 +70,8 @@ public class EditEventPage { public static final By GROUP_EVENT_UUID = By.xpath("//*[contains(text(),'Group id')]/../following-sibling::input[1]"); public static final By NEW_GROUP_EVENT_CREATED_MESSAGE = - By.xpath("//*[contains(text(),'New event group created')]"); + By.xpath( + "//*[contains(text(),'The selected event was successfully linked to this event group')]"); public static final By CREATE_DOCUMENT_BUTTON = By.cssSelector("[id='Create']"); public static final By EVENT_HANDOUT_COMBOBOX = By.cssSelector(".popupContent div[role='combobox'] div"); diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java index 4144e737de5..aaa2f7033e2 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java @@ -1036,6 +1036,8 @@ public EditEventSteps( () -> { webDriverHelpers.clickOnWebElementBySelector(FIRST_GROUP_ID); webDriverHelpers.clickOnWebElementBySelector(SAVE_BUTTON_FOR_POPUP_WINDOWS); + webDriverHelpers.waitUntilElementIsVisibleAndClickable(EVENT_DATA_SAVED_MESSAGE); + webDriverHelpers.clickOnWebElementBySelector(EVENT_DATA_SAVED_MESSAGE); }); When( @@ -1320,6 +1322,7 @@ public EditEventSteps( fillGroupEventName(groupEvent.getName()); webDriverHelpers.clickOnWebElementBySelector(SAVE_BUTTON_FOR_POPUP_WINDOWS); webDriverHelpers.waitUntilElementIsVisibleAndClickable(NEW_GROUP_EVENT_CREATED_MESSAGE); + webDriverHelpers.clickOnWebElementBySelector(NEW_GROUP_EVENT_CREATED_MESSAGE); }); When( diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature index bde6f2d6699..e6e6132061c 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature @@ -226,7 +226,6 @@ Feature: Create events @tmsLink=SORDEV-5571 @env_main Scenario: Event group screen using Group Id in grid Given API: I create a new event - And API: I check that POST call status code is 200 Given I log in as a National User And I click on the Events button from navbar @@ -236,6 +235,7 @@ Feature: Create events And I click on Link Event button on Edit Event Page And I click on first Event Group on the list in Link Event form And I click on SAVE button in Link Event to group form + And I click on successfully linked to this event group message popup in Link Event to group form And I click on the Events button from navbar And I click on Group Id in Events result on Event Directory Page And I click on Unlink Event button on Event Directory Page @@ -243,7 +243,6 @@ Feature: Create events @tmsLink=SORDEV-5570 @env_main Scenario: Testing Event screen Impact Given API: I create a new event - And API: I check that POST call status code is 200 Given I log in as a National User Then I open the last created event via api From 4cd122a041812553260032207fce1dc26627f71e Mon Sep 17 00:00:00 2001 From: Michal Kozakiewicz Date: Mon, 7 Aug 2023 16:00:31 +0200 Subject: [PATCH 171/174] SORQA-1054 Stabilize "Testing Event screen Impact" - added missing step --- .../events/EventDirectorySteps.java | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EventDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EventDirectorySteps.java index e018b5c5e61..4491da39a7c 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EventDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EventDirectorySteps.java @@ -33,17 +33,7 @@ import static org.sormas.e2etests.pages.application.cases.EditCasePage.VACCINATION_CARD_INFO_POPUP_TEXT; import static org.sormas.e2etests.pages.application.configuration.DocumentTemplatesPage.FILE_PICKER; import static org.sormas.e2etests.pages.application.contacts.ContactDirectoryPage.FIRST_CONTACT_ID; -import static org.sormas.e2etests.pages.application.events.EditEventPage.EVENT_MANAGEMENT_STATUS_CHECK; -import static org.sormas.e2etests.pages.application.events.EditEventPage.EVENT_PARTICIPANTS_TAB; -import static org.sormas.e2etests.pages.application.events.EditEventPage.FIRST_ARCHIVED_EVENT_PARTICIPANT; -import static org.sormas.e2etests.pages.application.events.EditEventPage.FIRST_EVENT_PARTICIPANT; -import static org.sormas.e2etests.pages.application.events.EditEventPage.FIRST_EVENT_PARTICIPANT_AFTER_IMPORT; -import static org.sormas.e2etests.pages.application.events.EditEventPage.FIRST_EVENT_PARTICIPANT_FROM_LIST; -import static org.sormas.e2etests.pages.application.events.EditEventPage.FIRST_PERSON_ID_IN_EVENT_PARTICIPANT_TAB; -import static org.sormas.e2etests.pages.application.events.EditEventPage.FIRST_RESULT_IN_EVENT_PARTICIPANT_TABLE; -import static org.sormas.e2etests.pages.application.events.EditEventPage.NEW_TASK_BUTTON; -import static org.sormas.e2etests.pages.application.events.EditEventPage.UUID_EDIT_EVENT; -import static org.sormas.e2etests.pages.application.events.EditEventPage.UUID_INPUT; +import static org.sormas.e2etests.pages.application.events.EditEventPage.*; import static org.sormas.e2etests.pages.application.events.EventDirectoryPage.APPLY_FILTER; import static org.sormas.e2etests.pages.application.events.EventDirectoryPage.BASIC_EVENT_EXPORT_BUTTON; import static org.sormas.e2etests.pages.application.events.EventDirectoryPage.BASIC_EXPORT_PARTICIPANT_BUTTON; @@ -447,6 +437,14 @@ public EventDirectorySteps( SAVE_BUTTON_IN_LINK_FORM); webDriverHelpers.clickOnWebElementBySelector(SAVE_BUTTON_IN_LINK_FORM); }); + + When( + "^I click on successfully linked to this event group message popup in Link Event to group form$", + () -> { + webDriverHelpers.waitUntilElementIsVisibleAndClickable(NEW_GROUP_EVENT_CREATED_MESSAGE); + webDriverHelpers.clickOnWebElementBySelector(NEW_GROUP_EVENT_CREATED_MESSAGE); + }); + When( "^I click on Linked Group Id on Edit Event Page$", () -> webDriverHelpers.clickOnWebElementBySelector(LINKED_EVENT_GROUP_ID)); From b8714819ca11fe446d7cb210987dc394073dcc7e Mon Sep 17 00:00:00 2001 From: Michal Kozakiewicz Date: Tue, 8 Aug 2023 08:30:22 +0200 Subject: [PATCH 172/174] SORQA-1055 Stabilize "SORMAS - Keycloak Synchronisation (manual sync)" - selectors has change --- .../pages/application/keycloak/KeycloakAdminConsolePage.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/keycloak/KeycloakAdminConsolePage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/keycloak/KeycloakAdminConsolePage.java index e8e467295af..5751835a97a 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/keycloak/KeycloakAdminConsolePage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/keycloak/KeycloakAdminConsolePage.java @@ -24,11 +24,11 @@ public class KeycloakAdminConsolePage { public static final By USER_ID = By.cssSelector("#options-menu-top-pagination > div.pf-c-options-menu > div > span > b"); public static final By RESULT_IN_TABLE = By.cssSelector("table tbody tr"); - public static final By ITEMS_PER_PAGE_BUTTON = By.cssSelector("#options-menu-bottom-toggle"); + public static final By ITEMS_PER_PAGE_BUTTON = By.id("users:title-top-toggle"); public static final By ONE_HUNDRED_PER_PAGE_BUTTON = By.xpath("//button[contains(text(), '100')]"); public static final By NEXT_PAGE_BUTTON = - By.cssSelector("#options-menu-top-pagination > nav > div:nth-child(2) > button"); + By.xpath("//*[@id='users:title-top-pagination']/nav/div[2]/button"); public static final By USER_ENABLE_DISABLE_SWITCH = By.cssSelector("#userEnabled"); public static final By USER_DISABLED = By.xpath("//span[contains(text(), 'Disabled')]"); public static final By SEARCH_USER_INPUT = By.xpath("//input[@placeholder='Search user']"); From 35b4b49984f745f590fa4420c8da95b107bfaa23 Mon Sep 17 00:00:00 2001 From: jen kins Date: Tue, 8 Aug 2023 15:08:01 +0200 Subject: [PATCH 173/174] Updated version number --- .../resources/doc/SORMAS_Data_Dictionary.xlsx | Bin 270913 -> 272444 bytes .../main/resources/doc/SORMAS_User_Roles.xlsx | Bin 33267 -> 33286 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/sormas-api/src/main/resources/doc/SORMAS_Data_Dictionary.xlsx b/sormas-api/src/main/resources/doc/SORMAS_Data_Dictionary.xlsx index a78c6189eebb494b963e93074c5f2ddf068188d3..a3856a657231b1d275ccaadaf96eae5183334b11 100644 GIT binary patch delta 93403 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 F{{xskAjbdz delta 92124 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 X@aNxe9O8$0r!RpNc$5C<|MLF;5g`^{ delta 12868 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 R--H%e3%G>;)gSqh{{ut9IWzzO From 91c59270ad2566f2730cc50585eedf29feeb37a1 Mon Sep 17 00:00:00 2001 From: jenkins Date: Tue, 8 Aug 2023 15:08:19 +0200 Subject: [PATCH 174/174] [GITFLOW]updating poms for branch'release-1.87.0' with non-snapshot versions --- sormas-api/pom.xml | 2 +- sormas-app/pom.xml | 2 +- sormas-backend/pom.xml | 2 +- sormas-base/pom.xml | 2 +- sormas-cargoserver/pom.xml | 2 +- sormas-ear/pom.xml | 2 +- sormas-keycloak-service-provider/pom.xml | 2 +- sormas-rest/pom.xml | 2 +- sormas-serverlibs/pom.xml | 2 +- sormas-ui/pom.xml | 2 +- sormas-widgetset/pom.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/sormas-api/pom.xml b/sormas-api/pom.xml index eb1b1b89a83..040069f527e 100644 --- a/sormas-api/pom.xml +++ b/sormas-api/pom.xml @@ -2,7 +2,7 @@ de.symeda.sormas sormas-base - 1.87.0-SNAPSHOT + 1.87.0 ../sormas-base 4.0.0 diff --git a/sormas-app/pom.xml b/sormas-app/pom.xml index f0b488d93bb..9580c19161e 100644 --- a/sormas-app/pom.xml +++ b/sormas-app/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.87.0-SNAPSHOT + 1.87.0 ../sormas-base 4.0.0 diff --git a/sormas-backend/pom.xml b/sormas-backend/pom.xml index a447aebf35a..37fb63ca1c5 100644 --- a/sormas-backend/pom.xml +++ b/sormas-backend/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.87.0-SNAPSHOT + 1.87.0 ../sormas-base 4.0.0 diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index 745eea5cfc7..95f4f81d8fc 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -5,7 +5,7 @@ de.symeda.sormas sormas-base pom - 1.87.0-SNAPSHOT + 1.87.0 3.6.3 diff --git a/sormas-cargoserver/pom.xml b/sormas-cargoserver/pom.xml index b01dc9b18a5..317f521ad8b 100644 --- a/sormas-cargoserver/pom.xml +++ b/sormas-cargoserver/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.87.0-SNAPSHOT + 1.87.0 ../sormas-base diff --git a/sormas-ear/pom.xml b/sormas-ear/pom.xml index 2b6d48f1228..504ca795ad1 100644 --- a/sormas-ear/pom.xml +++ b/sormas-ear/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.87.0-SNAPSHOT + 1.87.0 ../sormas-base diff --git a/sormas-keycloak-service-provider/pom.xml b/sormas-keycloak-service-provider/pom.xml index 35cf0fc8dd9..96ed1b75c73 100644 --- a/sormas-keycloak-service-provider/pom.xml +++ b/sormas-keycloak-service-provider/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.87.0-SNAPSHOT + 1.87.0 ../sormas-base 4.0.0 diff --git a/sormas-rest/pom.xml b/sormas-rest/pom.xml index e8c54fe44cc..4bf5bf94ea7 100644 --- a/sormas-rest/pom.xml +++ b/sormas-rest/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.87.0-SNAPSHOT + 1.87.0 ../sormas-base diff --git a/sormas-serverlibs/pom.xml b/sormas-serverlibs/pom.xml index f468ceb89e8..1e817f8b3ea 100644 --- a/sormas-serverlibs/pom.xml +++ b/sormas-serverlibs/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.87.0-SNAPSHOT + 1.87.0 ../sormas-base 4.0.0 diff --git a/sormas-ui/pom.xml b/sormas-ui/pom.xml index 9bdf3c48466..60f04448bd5 100644 --- a/sormas-ui/pom.xml +++ b/sormas-ui/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.87.0-SNAPSHOT + 1.87.0 ../sormas-base 4.0.0 diff --git a/sormas-widgetset/pom.xml b/sormas-widgetset/pom.xml index 2e65f34fbde..4cbe2bfe3d5 100644 --- a/sormas-widgetset/pom.xml +++ b/sormas-widgetset/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.87.0-SNAPSHOT + 1.87.0 ../sormas-base 4.0.0