diff --git a/docs/EXTERNAL_MESSAGES_ADAPTER.md b/docs/EXTERNAL_MESSAGES_ADAPTER.md
index 055bee1b5a9..9fdd21540e1 100644
--- a/docs/EXTERNAL_MESSAGES_ADAPTER.md
+++ b/docs/EXTERNAL_MESSAGES_ADAPTER.md
@@ -13,9 +13,6 @@ A minimal maven project structure for an external message adapter module is show
| | | | |-- MyExternalMessageFacadeEjb.java
| | |-- resources
| | | |-- version.txt
- | | |-- webapp
- | | | |-- META-INF
- | | | | |-- context.xml
| |-- test
| | |-- java
| | | |-- my.project
@@ -90,14 +87,6 @@ Example:
${project.name} ${project.version}
```
-### context.xml
-This xml is used to configure the context path of your external message adapter module.
-```xml
-
-
-
-```
-
### pom.xml
This is the maven project configuration file.
@@ -114,7 +103,7 @@ Example with default dependencies for java-ee, sormas-api, logging and testing:
1.85.0
- /my-message-adapter
+ my-message-adapter
8.0
1.7.30
@@ -171,7 +160,7 @@ Example with default dependencies for java-ee, sormas-api, logging and testing:
1.85.0
- /my-message-adapter
+ my-message-adapter
4.13.1
3.6.0
@@ -297,22 +286,15 @@ Example with default dependencies for java-ee, sormas-api, logging and testing:
-
org.apache.maven.plugins
maven-war-plugin
3.2.3
+ ${warName}
+
true
-
- src/main/webapp/META-INF
-
- context.xml
-
- /META-INF
- true
-
src/main/webapp
/
diff --git a/sormas-api/pom.xml b/sormas-api/pom.xml
index d8c6a1cf9e4..9a71ade2290 100644
--- a/sormas-api/pom.xml
+++ b/sormas-api/pom.xml
@@ -2,7 +2,7 @@
de.symeda.sormas
sormas-base
- 1.89.0-SNAPSHOT
+ 1.90.0-SNAPSHOT
../sormas-base
4.0.0
diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/environment/EnvironmentCriteria.java b/sormas-api/src/main/java/de/symeda/sormas/api/environment/EnvironmentCriteria.java
index 0142ad5e1fe..fa75867678f 100644
--- a/sormas-api/src/main/java/de/symeda/sormas/api/environment/EnvironmentCriteria.java
+++ b/sormas-api/src/main/java/de/symeda/sormas/api/environment/EnvironmentCriteria.java
@@ -6,6 +6,7 @@
import de.symeda.sormas.api.EntityRelevanceStatus;
import de.symeda.sormas.api.caze.InvestigationStatus;
import de.symeda.sormas.api.infrastructure.community.CommunityReferenceDto;
+import de.symeda.sormas.api.infrastructure.country.CountryReferenceDto;
import de.symeda.sormas.api.infrastructure.district.DistrictReferenceDto;
import de.symeda.sormas.api.infrastructure.region.RegionReferenceDto;
import de.symeda.sormas.api.user.UserReferenceDto;
@@ -32,6 +33,8 @@ public class EnvironmentCriteria extends BaseCriteria implements Serializable {
private static final long serialVersionUID = -2947852193651003088L;
private String freeText;
+ private String externalId;
+ private CountryReferenceDto country;
private RegionReferenceDto region;
private DistrictReferenceDto district;
private CommunityReferenceDto community;
@@ -47,6 +50,14 @@ public class EnvironmentCriteria extends BaseCriteria implements Serializable {
private Double gpsLatTo;
private Double gpsLonFrom;
private Double gpsLonTo;
+ /**
+ * Used for similarity detection at import
+ */
+ private Double gpsLat;
+ /**
+ * Used for similarity detection at import
+ */
+ private Double gpsLon;
@IgnoreForUrl
public String getFreeText() {
@@ -62,6 +73,33 @@ public void setFreeText(String freeText) {
this.freeText = freeText;
}
+ @IgnoreForUrl
+ public String getExternalId() {
+ return externalId;
+ }
+
+ public EnvironmentCriteria externalId(String externalId) {
+ this.externalId = externalId;
+ return this;
+ }
+
+ public void setExternalId(String externalId) {
+ this.externalId = externalId;
+ }
+
+ public CountryReferenceDto getCountry() {
+ return country;
+ }
+
+ public EnvironmentCriteria country(CountryReferenceDto country) {
+ this.country = country;
+ return this;
+ }
+
+ public void setCountry(CountryReferenceDto country) {
+ this.country = country;
+ }
+
public RegionReferenceDto getRegion() {
return region;
}
@@ -244,6 +282,32 @@ public void setGpsLonTo(Double gpsLonTo) {
this.gpsLonTo = gpsLonTo;
}
+ public Double getGpsLat() {
+ return gpsLat;
+ }
+
+ public EnvironmentCriteria gpsLat(Double gpsLat) {
+ this.gpsLat = gpsLat;
+ return this;
+ }
+
+ public void setGpsLat(Double gpsLat) {
+ this.gpsLat = gpsLat;
+ }
+
+ public Double getGpsLon() {
+ return gpsLon;
+ }
+
+ public EnvironmentCriteria gpsLon(Double gpsLon) {
+ this.gpsLon = gpsLon;
+ return this;
+ }
+
+ public void setGpsLon(Double gpsLon) {
+ this.gpsLon = gpsLon;
+ }
+
public void reportDateBetween(Date reportDateFrom, Date reportDateTo, DateFilterOption dateFilterOption) {
this.reportDateFrom = reportDateFrom;
this.reportDateTo = reportDateTo;
diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/environment/EnvironmentDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/environment/EnvironmentDto.java
index 1629f8b148a..830b6ecbff7 100644
--- a/sormas-api/src/main/java/de/symeda/sormas/api/environment/EnvironmentDto.java
+++ b/sormas-api/src/main/java/de/symeda/sormas/api/environment/EnvironmentDto.java
@@ -47,12 +47,12 @@ public class EnvironmentDto extends PseudonymizableDto {
public static final String DELETION_REASON = "deletionReason";
public static final String OTHER_DELETION_REASON = "otherDeletionReason";
- @NotNull
+ @NotNull(message = Validations.validReportDateTime)
private Date reportDate;
- @NotNull
+ @NotNull(message = Validations.validReportingUser)
private UserReferenceDto reportingUser;
@Size(max = FieldConstraints.CHARACTER_LIMIT_TEXT, message = Validations.textTooLong)
- @NotBlank
+ @NotBlank(message = Validations.environmentName)
private String environmentName;
@Size(max = FieldConstraints.CHARACTER_LIMIT_TEXT, message = Validations.textTooLong)
private String description;
@@ -61,7 +61,7 @@ public class EnvironmentDto extends PseudonymizableDto {
private UserReferenceDto responsibleUser;
@NotNull
private InvestigationStatus investigationStatus;
- @NotNull
+ @NotNull(message = Validations.environmentMedia)
private EnvironmentMedia environmentMedia;
private WaterType waterType;
@Size(max = FieldConstraints.CHARACTER_LIMIT_TEXT, message = Validations.textTooLong)
@@ -85,6 +85,7 @@ public class EnvironmentDto extends PseudonymizableDto {
public static EnvironmentDto build() {
final EnvironmentDto environment = new EnvironmentDto();
environment.setUuid(DataHelper.createUuid());
+ environment.setReportDate(new Date());
environment.setLocation(LocationDto.build());
environment.setInvestigationStatus(InvestigationStatus.PENDING);
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 b5e297b4e6e..52b80270624 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,13 +1,14 @@
package de.symeda.sormas.api.environment;
+import java.util.List;
+
import javax.ejb.Remote;
import de.symeda.sormas.api.CoreFacade;
-import java.util.List;
-
@Remote
public interface EnvironmentFacade extends CoreFacade {
- List getAllActiveUuids();
+ List getAllActiveUuids();
+
}
diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/externalmessage/ExternalMessageDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/externalmessage/ExternalMessageDto.java
index 37101f2e898..7bdbf52e0c3 100644
--- a/sormas-api/src/main/java/de/symeda/sormas/api/externalmessage/ExternalMessageDto.java
+++ b/sormas-api/src/main/java/de/symeda/sormas/api/externalmessage/ExternalMessageDto.java
@@ -155,6 +155,8 @@ public class ExternalMessageDto extends SormasToSormasShareableDto {
*/
private UserReferenceDto reportingUser;
+ private boolean automaticProcessingPossible;
+
public ExternalMessageType getType() {
return type;
}
@@ -497,4 +499,11 @@ public void setReportingUser(UserReferenceDto reportingUser) {
this.reportingUser = reportingUser;
}
+ public boolean isAutomaticProcessingPossible() {
+ return automaticProcessingPossible;
+ }
+
+ public void setAutomaticProcessingPossible(boolean automaticProcessingPossible) {
+ this.automaticProcessingPossible = automaticProcessingPossible;
+ }
}
diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/feature/FeatureType.java b/sormas-api/src/main/java/de/symeda/sormas/api/feature/FeatureType.java
index a0ed82c85c3..8a86101237b 100644
--- a/sormas-api/src/main/java/de/symeda/sormas/api/feature/FeatureType.java
+++ b/sormas-api/src/main/java/de/symeda/sormas/api/feature/FeatureType.java
@@ -125,7 +125,7 @@ public enum FeatureType {
new FeatureType[] {
SAMPLES_LAB },
null,
- null),
+ ImmutableMap.of(FeatureTypeProperty.FETCH_MODE, Boolean.FALSE)),
MANUAL_EXTERNAL_MESSAGES(true,
true,
new FeatureType[] {
diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/feature/FeatureTypeProperty.java b/sormas-api/src/main/java/de/symeda/sormas/api/feature/FeatureTypeProperty.java
index 1968d567991..6f4ec901d7f 100644
--- a/sormas-api/src/main/java/de/symeda/sormas/api/feature/FeatureTypeProperty.java
+++ b/sormas-api/src/main/java/de/symeda/sormas/api/feature/FeatureTypeProperty.java
@@ -28,7 +28,8 @@ public enum FeatureTypeProperty {
SHARE_ASSOCIATED_CONTACTS(Boolean.class),
SHARE_SAMPLES(Boolean.class),
SHARE_IMMUNIZATIONS(Boolean.class),
- SHARE_REPORTS(Boolean.class);
+ SHARE_REPORTS(Boolean.class),
+ FETCH_MODE(Boolean.class);
private final Class> returnType;
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 47f02bfb397..2d55e09db1e 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
@@ -491,6 +491,7 @@ public interface Strings {
String headingCreateNewContact = "headingCreateNewContact";
String headingCreateNewContactIssue = "headingCreateNewContactIssue";
String headingCreateNewEnvironment = "headingCreateNewEnvironment";
+ String headingCreateNewEnvironmentSample = "headingCreateNewEnvironmentSample";
String headingCreateNewEvent = "headingCreateNewEvent";
String headingCreateNewEventGroup = "headingCreateNewEventGroup";
String headingCreateNewEventParticipant = "headingCreateNewEventParticipant";
@@ -1219,6 +1220,7 @@ public interface Strings {
String messageDistrictsArchived = "messageDistrictsArchived";
String messageDistrictsDearchived = "messageDistrictsDearchived";
String messageDontShareWithReportingToolWarning = "messageDontShareWithReportingToolWarning";
+ String messageDuplicateEnvironmentFound = "messageDuplicateEnvironmentFound";
String messageEnterSms = "messageEnterSms";
String messageEntitiesNotEditable = "messageEntitiesNotEditable";
String messageEntityNotFound = "messageEntityNotFound";
diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Validations.java b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Validations.java
index a62fdbb453f..8badc4f3281 100644
--- a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Validations.java
+++ b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Validations.java
@@ -47,6 +47,8 @@ public interface Validations {
String duplicateEpidNumber = "duplicateEpidNumber";
String duplicateExternalToken = "duplicateExternalToken";
String emptyOverwrittenFollowUpUntilDate = "emptyOverwrittenFollowUpUntilDate";
+ String environmentMedia = "environmentMedia";
+ String environmentName = "environmentName";
String environmentWaterFieldsSetWithNotWaterMedia = "environmentWaterFieldsSetWithNotWaterMedia";
String errorsInForm = "errorsInForm";
String eventSubordinateEventFromDateFilterValidation = "eventSubordinateEventFromDateFilterValidation";
diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/importexport/ImportLineResultDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/importexport/ImportLineResultDto.java
index f07afc13805..54e75f08afb 100644
--- a/sormas-api/src/main/java/de/symeda/sormas/api/importexport/ImportLineResultDto.java
+++ b/sormas-api/src/main/java/de/symeda/sormas/api/importexport/ImportLineResultDto.java
@@ -69,7 +69,11 @@ public static ImportLineResultDto errorResult(String message) {
}
public static ImportLineResultDto duplicateResult(E entities) {
- return new ImportLineResultDto<>(ImportLineResult.DUPLICATE, null, entities);
+ return duplicateResult(entities, null);
+ }
+
+ public static ImportLineResultDto duplicateResult(E entities, String message) {
+ return new ImportLineResultDto<>(ImportLineResult.DUPLICATE, message, entities);
}
public static ImportLineResultDto skippedResult(String message) {
diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/user/UserRight.java b/sormas-api/src/main/java/de/symeda/sormas/api/user/UserRight.java
index d5d05a905c3..4f44bc0477a 100644
--- a/sormas-api/src/main/java/de/symeda/sormas/api/user/UserRight.java
+++ b/sormas-api/src/main/java/de/symeda/sormas/api/user/UserRight.java
@@ -257,9 +257,6 @@ public enum UserRight {
EXTERNAL_MESSAGE_VIEW(UserRightGroup.EXTERNAL),
EXTERNAL_MESSAGE_PROCESS(UserRightGroup.EXTERNAL, UserRight._EXTERNAL_MESSAGE_VIEW,
- UserRight._CASE_CREATE, UserRight._CASE_EDIT,
- UserRight._CONTACT_CREATE, UserRight._CONTACT_EDIT,
- UserRight._EVENT_CREATE, UserRight._EVENT_EDIT, UserRight._EVENTPARTICIPANT_CREATE, UserRight._EVENTPARTICIPANT_EDIT,
UserRight._SAMPLE_CREATE, UserRight._SAMPLE_EDIT, UserRight._PATHOGEN_TEST_CREATE, UserRight._PATHOGEN_TEST_EDIT, UserRight._PATHOGEN_TEST_DELETE,
UserRight._IMMUNIZATION_CREATE, UserRight._IMMUNIZATION_EDIT, UserRight._IMMUNIZATION_DELETE),
EXTERNAL_MESSAGE_PUSH(UserRightGroup.EXTERNAL),
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 11d151e3970..0c99f50a5cc 100644
Binary files a/sormas-api/src/main/resources/doc/SORMAS_Data_Dictionary.xlsx and b/sormas-api/src/main/resources/doc/SORMAS_Data_Dictionary.xlsx differ
diff --git a/sormas-api/src/main/resources/doc/SORMAS_User_Roles.xlsx b/sormas-api/src/main/resources/doc/SORMAS_User_Roles.xlsx
index e36a507175e..e0aa6bdabe6 100644
Binary files a/sormas-api/src/main/resources/doc/SORMAS_User_Roles.xlsx and b/sormas-api/src/main/resources/doc/SORMAS_User_Roles.xlsx differ
diff --git a/sormas-api/src/main/resources/strings.properties b/sormas-api/src/main/resources/strings.properties
index f16ae41be30..af9ea87be59 100644
--- a/sormas-api/src/main/resources/strings.properties
+++ b/sormas-api/src/main/resources/strings.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted: %
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_ar-SA.properties b/sormas-api/src/main/resources/strings_ar-SA.properties
index 435ea2b70fd..8e90fc167a8 100644
--- a/sormas-api/src/main/resources/strings_ar-SA.properties
+++ b/sormas-api/src/main/resources/strings_ar-SA.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_cs-CZ.properties b/sormas-api/src/main/resources/strings_cs-CZ.properties
index 64266a3ce12..54a7ab696f7 100644
--- a/sormas-api/src/main/resources/strings_cs-CZ.properties
+++ b/sormas-api/src/main/resources/strings_cs-CZ.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Vytvořit novou léčbu
headingCreateNewUser = Vytvořit nového uživatele
headingCreateNewUserRole = Vytvořit novou uživatelskou roli
headingCreateNewVisit = Vytvořit novou návštěvu
+headingCreateNewEnvironmentSample = Vytvořit nový vzorek prostředí
headingCreatePathogenTestResult = Vytvořit nový výsledek testu patogenu
headingDatabaseExportFailed = Export databáze selhal
headingDearchiveCampaign = Vyjmout z archivu kampaň
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Vzorek prostředí uložen
+messageDuplicateEnvironmentFound = Podobné prostředí již existuje v databázi (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = Klasifikace případu %s se změnila na %s.
diff --git a/sormas-api/src/main/resources/strings_de-CH.properties b/sormas-api/src/main/resources/strings_de-CH.properties
index 4fbf9885135..1b50f8241fa 100644
--- a/sormas-api/src/main/resources/strings_de-CH.properties
+++ b/sormas-api/src/main/resources/strings_de-CH.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Neue Behandlung erstellen
headingCreateNewUser = Neuen Benutzer erstellen
headingCreateNewUserRole = Neue Benutzerrolle erstellen
headingCreateNewVisit = Neuen Anruf erstellen
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Neues Erregertestergebnis erstellen
headingDatabaseExportFailed = Datenbank-Export fehlgeschlagen
headingDearchiveCampaign = Kampagne de-archivieren
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = Die Falldefinitionskategorie des Falls %s wurde auf %s geändert.
diff --git a/sormas-api/src/main/resources/strings_de-DE.properties b/sormas-api/src/main/resources/strings_de-DE.properties
index 629b0bebf40..91b3442157e 100644
--- a/sormas-api/src/main/resources/strings_de-DE.properties
+++ b/sormas-api/src/main/resources/strings_de-DE.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Neue Behandlung erstellen
headingCreateNewUser = Neuen Benutzer erstellen
headingCreateNewUserRole = Neue Benutzerrolle erstellen
headingCreateNewVisit = Neuen Anruf erstellen
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Neues Erregertestergebnis erstellen
headingDatabaseExportFailed = Datenbank-Export fehlgeschlagen
headingDearchiveCampaign = Kampagne de-archivieren
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = Die Falldefinitionskategorie des Falls %s wurde auf %s geändert.
diff --git a/sormas-api/src/main/resources/strings_en-AF.properties b/sormas-api/src/main/resources/strings_en-AF.properties
index 943d7d7832f..0f0b52b47b1 100644
--- a/sormas-api/src/main/resources/strings_en-AF.properties
+++ b/sormas-api/src/main/resources/strings_en-AF.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_en-GH.properties b/sormas-api/src/main/resources/strings_en-GH.properties
index 5229bdd6896..40620d3a636 100644
--- a/sormas-api/src/main/resources/strings_en-GH.properties
+++ b/sormas-api/src/main/resources/strings_en-GH.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_en-NG.properties b/sormas-api/src/main/resources/strings_en-NG.properties
index 8d9b3b864a5..605bba36ff1 100644
--- a/sormas-api/src/main/resources/strings_en-NG.properties
+++ b/sormas-api/src/main/resources/strings_en-NG.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_es-CU.properties b/sormas-api/src/main/resources/strings_es-CU.properties
index c97df9bfff4..0b08cf8d379 100644
--- a/sormas-api/src/main/resources/strings_es-CU.properties
+++ b/sormas-api/src/main/resources/strings_es-CU.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Crear nuevo tratamiento
headingCreateNewUser = Crear nuevo usuario
headingCreateNewUserRole = Crear nuevo rol de usuario
headingCreateNewVisit = Crear nueva visita
+headingCreateNewEnvironmentSample = Crear nueva muestra ambiental
headingCreatePathogenTestResult = Crear un nuevo resultado de prueba de patógeno
headingDatabaseExportFailed = Falló la exportación de la base de datos
headingDearchiveCampaign = Desarchivar campaña
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s muestras ambientales no eliminadas
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s muestras ambientales no eliminadas por no estar en jurisdicción o posesión\: %s
messageEnvironmentSamplesRestored = Todas las muestras ambientales seleccionadas fueron restauradas
messageEnvironmentSampleSaved = Se guardó la muestra ambiental
+messageDuplicateEnvironmentFound = Un ambiente similar ya existe en la base de datos (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = La clasificación del caso %s se cambió a %s.
diff --git a/sormas-api/src/main/resources/strings_es-ES.properties b/sormas-api/src/main/resources/strings_es-ES.properties
index 96b74f8b0d7..08b6ff34f21 100644
--- a/sormas-api/src/main/resources/strings_es-ES.properties
+++ b/sormas-api/src/main/resources/strings_es-ES.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_fa-AF.properties b/sormas-api/src/main/resources/strings_fa-AF.properties
index 96b74f8b0d7..08b6ff34f21 100644
--- a/sormas-api/src/main/resources/strings_fa-AF.properties
+++ b/sormas-api/src/main/resources/strings_fa-AF.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_fi-FI.properties b/sormas-api/src/main/resources/strings_fi-FI.properties
index 33e43f42953..9de78ffb185 100644
--- a/sormas-api/src/main/resources/strings_fi-FI.properties
+++ b/sormas-api/src/main/resources/strings_fi-FI.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Lisää uusi hoito
headingCreateNewUser = Luo uusi käyttäjä
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Luo uusi käynti
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Lisää uusi patogeenitestin tulos
headingDatabaseExportFailed = Tietokannan vienti epäonnistui
headingDearchiveCampaign = Palauta kampanja arkistosta
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = Potilaan %s luokitus on muuttunut luokkaan %s.
diff --git a/sormas-api/src/main/resources/strings_fil-PH.properties b/sormas-api/src/main/resources/strings_fil-PH.properties
index 96b74f8b0d7..08b6ff34f21 100644
--- a/sormas-api/src/main/resources/strings_fil-PH.properties
+++ b/sormas-api/src/main/resources/strings_fil-PH.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_fj-FJ.properties b/sormas-api/src/main/resources/strings_fj-FJ.properties
index 96b74f8b0d7..08b6ff34f21 100644
--- a/sormas-api/src/main/resources/strings_fj-FJ.properties
+++ b/sormas-api/src/main/resources/strings_fj-FJ.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_fr-CD.properties b/sormas-api/src/main/resources/strings_fr-CD.properties
index 75729e0f8a7..9f8d9e7ea9e 100644
--- a/sormas-api/src/main/resources/strings_fr-CD.properties
+++ b/sormas-api/src/main/resources/strings_fr-CD.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_fr-CH.properties b/sormas-api/src/main/resources/strings_fr-CH.properties
index f0370ffc9ac..694c6af470d 100644
--- a/sormas-api/src/main/resources/strings_fr-CH.properties
+++ b/sormas-api/src/main/resources/strings_fr-CH.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Créer un nouveau traitement
headingCreateNewUser = Créer un nouvel utilisateur
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Créer de nouvelles visites
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new sample test result
headingDatabaseExportFailed = Échec de l'exportation de base de données
headingDearchiveCampaign = Désarchiver cette campagne
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = La classification du cas %s a changé en %s.
diff --git a/sormas-api/src/main/resources/strings_fr-FR.properties b/sormas-api/src/main/resources/strings_fr-FR.properties
index 6d77b4131dd..47d74f16a50 100644
--- a/sormas-api/src/main/resources/strings_fr-FR.properties
+++ b/sormas-api/src/main/resources/strings_fr-FR.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Créer un nouveau traitement
headingCreateNewUser = Créer nouvel utilisateur
headingCreateNewUserRole = Créer nouveau rôle d'utilisateur
headingCreateNewVisit = Créer de nouvelles visites
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new sample test result
headingDatabaseExportFailed = Échec de l'exportation de base de données
headingDearchiveCampaign = Désarchiver cette campagne
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = Un environnement similaire existe déjà dans la base de données (UUID \: %s)
# Notifications
notificationCaseClassificationChanged = La classification du cas %s a changé en %s.
diff --git a/sormas-api/src/main/resources/strings_fr-TN.properties b/sormas-api/src/main/resources/strings_fr-TN.properties
index 53e3bb4f19c..4884f764928 100644
--- a/sormas-api/src/main/resources/strings_fr-TN.properties
+++ b/sormas-api/src/main/resources/strings_fr-TN.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Créer un nouveau traitement
headingCreateNewUser = Créer nouvel utilisateur
headingCreateNewUserRole = Créer nouveau rôle d'utilisateur
headingCreateNewVisit = Créer de nouvelles visites
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new sample test result
headingDatabaseExportFailed = Échec de l'exportation de base de données
headingDearchiveCampaign = Désarchiver cette campagne
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = La classification du cas %s a changé en %s.
diff --git a/sormas-api/src/main/resources/strings_hi-IN.properties b/sormas-api/src/main/resources/strings_hi-IN.properties
index 96b74f8b0d7..08b6ff34f21 100644
--- a/sormas-api/src/main/resources/strings_hi-IN.properties
+++ b/sormas-api/src/main/resources/strings_hi-IN.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_hr-HR.properties b/sormas-api/src/main/resources/strings_hr-HR.properties
index 96b74f8b0d7..08b6ff34f21 100644
--- a/sormas-api/src/main/resources/strings_hr-HR.properties
+++ b/sormas-api/src/main/resources/strings_hr-HR.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_it-CH.properties b/sormas-api/src/main/resources/strings_it-CH.properties
index 53518d32651..18f3342eee2 100644
--- a/sormas-api/src/main/resources/strings_it-CH.properties
+++ b/sormas-api/src/main/resources/strings_it-CH.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Crea nuovo trattamento
headingCreateNewUser = Crea nuovo utente
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Crea nuova visita
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Crea nuovo risultato di test patogeno
headingDatabaseExportFailed = Esportazione della banca dati non riuscita
headingDearchiveCampaign = Disarchivia campagna
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = La classificazione del caso %s è cambiata in %s.
diff --git a/sormas-api/src/main/resources/strings_it-IT.properties b/sormas-api/src/main/resources/strings_it-IT.properties
index 57d82e83f7f..1add3183ac0 100644
--- a/sormas-api/src/main/resources/strings_it-IT.properties
+++ b/sormas-api/src/main/resources/strings_it-IT.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Crea nuovo trattamento
headingCreateNewUser = Crea nuovo utente
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Crea nuova visita
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Crea nuovo risultato di test patogeno
headingDatabaseExportFailed = Esportazione della banca dati non riuscita
headingDearchiveCampaign = Disarchivia campagna
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = La classificazione del caso %s è cambiata in %s.
diff --git a/sormas-api/src/main/resources/strings_ja-JP.properties b/sormas-api/src/main/resources/strings_ja-JP.properties
index 96b74f8b0d7..08b6ff34f21 100644
--- a/sormas-api/src/main/resources/strings_ja-JP.properties
+++ b/sormas-api/src/main/resources/strings_ja-JP.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_ne-NP.properties b/sormas-api/src/main/resources/strings_ne-NP.properties
index 435ea2b70fd..8e90fc167a8 100644
--- a/sormas-api/src/main/resources/strings_ne-NP.properties
+++ b/sormas-api/src/main/resources/strings_ne-NP.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_nl-NL.properties b/sormas-api/src/main/resources/strings_nl-NL.properties
index 96b74f8b0d7..08b6ff34f21 100644
--- a/sormas-api/src/main/resources/strings_nl-NL.properties
+++ b/sormas-api/src/main/resources/strings_nl-NL.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_no-NO.properties b/sormas-api/src/main/resources/strings_no-NO.properties
index 96b74f8b0d7..08b6ff34f21 100644
--- a/sormas-api/src/main/resources/strings_no-NO.properties
+++ b/sormas-api/src/main/resources/strings_no-NO.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_pl-PL.properties b/sormas-api/src/main/resources/strings_pl-PL.properties
index 0c0518ef5cb..ba27e26271c 100644
--- a/sormas-api/src/main/resources/strings_pl-PL.properties
+++ b/sormas-api/src/main/resources/strings_pl-PL.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_ps-AF.properties b/sormas-api/src/main/resources/strings_ps-AF.properties
index 075abf79743..447c5b7a84f 100644
--- a/sormas-api/src/main/resources/strings_ps-AF.properties
+++ b/sormas-api/src/main/resources/strings_ps-AF.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_pt-PT.properties b/sormas-api/src/main/resources/strings_pt-PT.properties
index 96b74f8b0d7..08b6ff34f21 100644
--- a/sormas-api/src/main/resources/strings_pt-PT.properties
+++ b/sormas-api/src/main/resources/strings_pt-PT.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_ro-RO.properties b/sormas-api/src/main/resources/strings_ro-RO.properties
index 96b74f8b0d7..08b6ff34f21 100644
--- a/sormas-api/src/main/resources/strings_ro-RO.properties
+++ b/sormas-api/src/main/resources/strings_ro-RO.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_ru-RU.properties b/sormas-api/src/main/resources/strings_ru-RU.properties
index 2ebc595ac56..91870dc1b45 100644
--- a/sormas-api/src/main/resources/strings_ru-RU.properties
+++ b/sormas-api/src/main/resources/strings_ru-RU.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_sv-SE.properties b/sormas-api/src/main/resources/strings_sv-SE.properties
index 96b74f8b0d7..08b6ff34f21 100644
--- a/sormas-api/src/main/resources/strings_sv-SE.properties
+++ b/sormas-api/src/main/resources/strings_sv-SE.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_sw-KE.properties b/sormas-api/src/main/resources/strings_sw-KE.properties
index 96b74f8b0d7..08b6ff34f21 100644
--- a/sormas-api/src/main/resources/strings_sw-KE.properties
+++ b/sormas-api/src/main/resources/strings_sw-KE.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_tr-TR.properties b/sormas-api/src/main/resources/strings_tr-TR.properties
index 96b74f8b0d7..08b6ff34f21 100644
--- a/sormas-api/src/main/resources/strings_tr-TR.properties
+++ b/sormas-api/src/main/resources/strings_tr-TR.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_uk-UA.properties b/sormas-api/src/main/resources/strings_uk-UA.properties
index 96b74f8b0d7..08b6ff34f21 100644
--- a/sormas-api/src/main/resources/strings_uk-UA.properties
+++ b/sormas-api/src/main/resources/strings_uk-UA.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/strings_ur-PK.properties b/sormas-api/src/main/resources/strings_ur-PK.properties
index 684297c64f4..54ce21ad5e2 100644
--- a/sormas-api/src/main/resources/strings_ur-PK.properties
+++ b/sormas-api/src/main/resources/strings_ur-PK.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = نیاعلاج لکھیں
headingCreateNewUser = نیا صارف بنائیں
headingCreateNewUserRole = نیا صارف کردار بنائیں
headingCreateNewVisit = نئے دورے بنائیں
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = نئے پیتھوجین ٹیسٹ کا نتیجہ بنائیں
headingDatabaseExportFailed = ڈیٹا بیس ایکسپورٹ ناکام ہو گیا
headingDearchiveCampaign = مہمات کو ڈی آرکائیو کريں
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = کیس %s کی درجہ بندی %s میں تبدیل ہو گئی ہے۔
diff --git a/sormas-api/src/main/resources/strings_zh-CN.properties b/sormas-api/src/main/resources/strings_zh-CN.properties
index 435eaf47553..00a580d11b4 100644
--- a/sormas-api/src/main/resources/strings_zh-CN.properties
+++ b/sormas-api/src/main/resources/strings_zh-CN.properties
@@ -497,6 +497,7 @@ headingCreateNewTreatment = Create new treatment
headingCreateNewUser = Create new user
headingCreateNewUserRole = Create new user role
headingCreateNewVisit = Create new visit
+headingCreateNewEnvironmentSample = Create new environment sample
headingCreatePathogenTestResult = Create new pathogen test result
headingDatabaseExportFailed = Database export failed
headingDearchiveCampaign = De-Archive campaign
@@ -1462,6 +1463,7 @@ messageCountEnvironmentSamplesNotDeleted = %s environment samples not deleted\:
messageCountEnvironmentSamplesNotDeletedAccessDeniedReason = %s environment samples not deleted because they are not in jurisdiction or owned\: %s
messageEnvironmentSamplesRestored = All selected environment samples have been restored
messageEnvironmentSampleSaved = Environment sample saved
+messageDuplicateEnvironmentFound = A similar environment already exists in the database (UUID\: %s)
# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
diff --git a/sormas-api/src/main/resources/validations.properties b/sormas-api/src/main/resources/validations.properties
index 3f7f831b80a..8ac625e75f5 100644
--- a/sormas-api/src/main/resources/validations.properties
+++ b/sormas-api/src/main/resources/validations.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_ar-SA.properties b/sormas-api/src/main/resources/validations_ar-SA.properties
index 59273b324ae..bdbe85a67dd 100644
--- a/sormas-api/src/main/resources/validations_ar-SA.properties
+++ b/sormas-api/src/main/resources/validations_ar-SA.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_cs-CZ.properties b/sormas-api/src/main/resources/validations_cs-CZ.properties
index a7c8ec12170..7adcd40524c 100644
--- a/sormas-api/src/main/resources/validations_cs-CZ.properties
+++ b/sormas-api/src/main/resources/validations_cs-CZ.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=Návštěva nemůže být delší než %d dní před za
visitDate = Musíte zadat datum návštěvy.
visitSymptoms = Musíte specifikovat příznaky návštěvy.
visitStatus = Musíte zadat stav návštěvy.
+environmentName = Musíte zadat název prostředí
+environmentMedia = Musíte zadat média prostředí
softApproximateAgeTooHigh = Ujistěte se, že tato přibližná věková hodnota je správná; pokud je to možné, změňte ji na hodnotu nižší než 150.
validPointOfEntry = Musíte zadat platné místo vstupu
exportNoNameSpecified = Zadejte název pro konfiguraci exportu
diff --git a/sormas-api/src/main/resources/validations_de-CH.properties b/sormas-api/src/main/resources/validations_de-CH.properties
index ca2aeaff9d1..fdb23cde5dc 100644
--- a/sormas-api/src/main/resources/validations_de-CH.properties
+++ b/sormas-api/src/main/resources/validations_de-CH.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=Der Besuch darf nicht länger als %d Tage vor dem Einse
visitDate = Sie müssen das Besuchsdatum spezifizieren.
visitSymptoms = Sie müssen das Symptom für den Besuch spezifizieren.
visitStatus = Sie müssen den Status des Besuchs spezifizieren.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Bitte stellen Sie sicher, dass dieser ungefähre Alterswert korrekt ist; falls zutreffend, ändern Sie ihn auf einen Wert unter 150.
validPointOfEntry = Sie müssen einen gültigen Einreiseort angeben
exportNoNameSpecified = Bitte geben Sie einen Namen für Ihre Exporteinstellungen ein
diff --git a/sormas-api/src/main/resources/validations_de-DE.properties b/sormas-api/src/main/resources/validations_de-DE.properties
index adaec25e0d9..50c1173ca16 100644
--- a/sormas-api/src/main/resources/validations_de-DE.properties
+++ b/sormas-api/src/main/resources/validations_de-DE.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=Der Besuch darf nicht länger als %d Tage vor dem Ausbr
visitDate = Sie müssen das Besuchsdatum spezifizieren.
visitSymptoms = Sie müssen das Symptom für den Besuch spezifizieren.
visitStatus = Sie müssen den Status des Besuchs spezifizieren.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Bitte stellen Sie sicher, dass dieser ungefähre Alterswert korrekt ist; falls zutreffend, ändern Sie ihn auf einen Wert unter 150.
validPointOfEntry = Sie müssen einen gültigen Einreiseort angeben
exportNoNameSpecified = Bitte geben Sie einen Namen für Ihre Exporteinstellungen ein
diff --git a/sormas-api/src/main/resources/validations_en-AF.properties b/sormas-api/src/main/resources/validations_en-AF.properties
index 02db5e17d22..642dae3eb50 100644
--- a/sormas-api/src/main/resources/validations_en-AF.properties
+++ b/sormas-api/src/main/resources/validations_en-AF.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_en-GH.properties b/sormas-api/src/main/resources/validations_en-GH.properties
index b9c4e33b17a..bf778184785 100644
--- a/sormas-api/src/main/resources/validations_en-GH.properties
+++ b/sormas-api/src/main/resources/validations_en-GH.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_en-NG.properties b/sormas-api/src/main/resources/validations_en-NG.properties
index 59273b324ae..bdbe85a67dd 100644
--- a/sormas-api/src/main/resources/validations_en-NG.properties
+++ b/sormas-api/src/main/resources/validations_en-NG.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_es-CU.properties b/sormas-api/src/main/resources/validations_es-CU.properties
index bc979cea33f..b1821295872 100644
--- a/sormas-api/src/main/resources/validations_es-CU.properties
+++ b/sormas-api/src/main/resources/validations_es-CU.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=La visita no puede ser más de %d días antes del inici
visitDate = Debe especificar una fecha de visita.
visitSymptoms = Debe especificar síntomas para una visita.
visitStatus = Debe especificar el estado para una visita.
+environmentName = Debe especificar un nombre de ambiente
+environmentMedia = Debe especificar los medios del ambiente
softApproximateAgeTooHigh = Por favor, asegúrese de que este valor aproximado de edad es correcto; si es aplicable, cámbielo a un valor menor que 150.
validPointOfEntry = Debe especificar un punto de entrada válido
exportNoNameSpecified = Por favor, ingrese un nombre para su configuración de exportación
diff --git a/sormas-api/src/main/resources/validations_es-ES.properties b/sormas-api/src/main/resources/validations_es-ES.properties
index 59273b324ae..bdbe85a67dd 100644
--- a/sormas-api/src/main/resources/validations_es-ES.properties
+++ b/sormas-api/src/main/resources/validations_es-ES.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_fa-AF.properties b/sormas-api/src/main/resources/validations_fa-AF.properties
index 59273b324ae..bdbe85a67dd 100644
--- a/sormas-api/src/main/resources/validations_fa-AF.properties
+++ b/sormas-api/src/main/resources/validations_fa-AF.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_fi-FI.properties b/sormas-api/src/main/resources/validations_fi-FI.properties
index 0c802875c77..39d4496dcc1 100644
--- a/sormas-api/src/main/resources/validations_fi-FI.properties
+++ b/sormas-api/src/main/resources/validations_fi-FI.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = Käyntipäivä on määriteltävä.
visitSymptoms = Sinun täytyy määrittää oireet käynnille.
visitStatus = Sinun täytyy määrittää käynnille tila.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Varmista, että tämä arvio iälle on oikein; jos mahdollista, aseta arvioksi pienempi luku kuin 150.
validPointOfEntry = Sinun täytyy valita tietokannasta löytyvä maahantulopaikka
exportNoNameSpecified = Anna nimi vientiasetuksillesi
diff --git a/sormas-api/src/main/resources/validations_fil-PH.properties b/sormas-api/src/main/resources/validations_fil-PH.properties
index 59273b324ae..bdbe85a67dd 100644
--- a/sormas-api/src/main/resources/validations_fil-PH.properties
+++ b/sormas-api/src/main/resources/validations_fil-PH.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_fj-FJ.properties b/sormas-api/src/main/resources/validations_fj-FJ.properties
index 59273b324ae..bdbe85a67dd 100644
--- a/sormas-api/src/main/resources/validations_fj-FJ.properties
+++ b/sormas-api/src/main/resources/validations_fj-FJ.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_fr-CD.properties b/sormas-api/src/main/resources/validations_fr-CD.properties
index 59273b324ae..bdbe85a67dd 100644
--- a/sormas-api/src/main/resources/validations_fr-CD.properties
+++ b/sormas-api/src/main/resources/validations_fr-CD.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_fr-CH.properties b/sormas-api/src/main/resources/validations_fr-CH.properties
index 83ba3554a38..81bfc0652e4 100644
--- a/sormas-api/src/main/resources/validations_fr-CH.properties
+++ b/sormas-api/src/main/resources/validations_fr-CH.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=La visite ne peut pas être plus de %d jours avant le d
visitDate = Vous devez spécifier une date de visite.
visitSymptoms = Vous devez spécifier les symptômes pour une visite.
visitStatus = Vous devez spécifier le statut pour une visite.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Veuillez vous assurer que cette valeur approximative d'âge est correcte; si applicable, changez-la à une valeur inférieure à 150.
validPointOfEntry = Vous devez spécifier un point d'entrée valide
exportNoNameSpecified = Veuillez saisir un nom pour votre configuration d'exportation
diff --git a/sormas-api/src/main/resources/validations_fr-FR.properties b/sormas-api/src/main/resources/validations_fr-FR.properties
index f9337da9d85..630a07a749c 100644
--- a/sormas-api/src/main/resources/validations_fr-FR.properties
+++ b/sormas-api/src/main/resources/validations_fr-FR.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=La visite ne peut pas être plus de %d jours avant l'ap
visitDate = Vous devez spécifier une date de visite.
visitSymptoms = Vous devez spécifier les symptômes pour une visite.
visitStatus = Vous devez spécifier le statut pour une visite.
+environmentName = Vous devez spécifier un nom d'environnement
+environmentMedia = Vous devez spécifier le média d'environnement
softApproximateAgeTooHigh = Veuillez vous assurer que cette valeur approximative d'âge est correcte; si applicable, changez-la à une valeur inférieure à 150.
validPointOfEntry = Vous devez spécifier un point d'entrée valide
exportNoNameSpecified = Veuillez saisir un nom pour votre configuration d'exportation
diff --git a/sormas-api/src/main/resources/validations_fr-TN.properties b/sormas-api/src/main/resources/validations_fr-TN.properties
index 63c02a383f4..6a2958ec325 100644
--- a/sormas-api/src/main/resources/validations_fr-TN.properties
+++ b/sormas-api/src/main/resources/validations_fr-TN.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=La visite ne peut pas être plus de %d jours avant l'ap
visitDate = Vous devez spécifier une date de visite.
visitSymptoms = Vous devez spécifier les symptômes pour une visite.
visitStatus = Vous devez spécifier le statut pour une visite.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Veuillez vous assurer que cette valeur approximative d'âge est correcte; si applicable, changez-la à une valeur inférieure à 150.
validPointOfEntry = Vous devez spécifier un point d'entrée valide
exportNoNameSpecified = Veuillez saisir un nom pour votre configuration d'exportation
diff --git a/sormas-api/src/main/resources/validations_hi-IN.properties b/sormas-api/src/main/resources/validations_hi-IN.properties
index 59273b324ae..bdbe85a67dd 100644
--- a/sormas-api/src/main/resources/validations_hi-IN.properties
+++ b/sormas-api/src/main/resources/validations_hi-IN.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_hr-HR.properties b/sormas-api/src/main/resources/validations_hr-HR.properties
index 59273b324ae..bdbe85a67dd 100644
--- a/sormas-api/src/main/resources/validations_hr-HR.properties
+++ b/sormas-api/src/main/resources/validations_hr-HR.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_it-CH.properties b/sormas-api/src/main/resources/validations_it-CH.properties
index e38a5fe2d3b..09976eb3d3a 100644
--- a/sormas-api/src/main/resources/validations_it-CH.properties
+++ b/sormas-api/src/main/resources/validations_it-CH.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=La visita non può essere più di %d giorni prima dell'
visitDate = Specificare una data della visita.
visitSymptoms = Specificare i sintomi per una visita.
visitStatus = Specificare lo status per una visita.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Assicurati che questa stima dell'età sia corretta; se del caso, modificala in un valore inferiore a 150.
validPointOfEntry = Specificare un punto di entrata valido
exportNoNameSpecified = Inserire un nome per la configurazione di esportazione
diff --git a/sormas-api/src/main/resources/validations_it-IT.properties b/sormas-api/src/main/resources/validations_it-IT.properties
index 2acdeb3a8f4..3246e96c294 100644
--- a/sormas-api/src/main/resources/validations_it-IT.properties
+++ b/sormas-api/src/main/resources/validations_it-IT.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = Specificare una data della visita.
visitSymptoms = Specificare i sintomi per una visita.
visitStatus = Specificare lo status per una visita.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Assicurati che questa stima dell'età sia corretta; se del caso, modificala in un valore inferiore a 150.
validPointOfEntry = Specificare un punto di entrata valido
exportNoNameSpecified = Inserire un nome per la configurazione di esportazione
diff --git a/sormas-api/src/main/resources/validations_ja-JP.properties b/sormas-api/src/main/resources/validations_ja-JP.properties
index 59273b324ae..bdbe85a67dd 100644
--- a/sormas-api/src/main/resources/validations_ja-JP.properties
+++ b/sormas-api/src/main/resources/validations_ja-JP.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_ne-NP.properties b/sormas-api/src/main/resources/validations_ne-NP.properties
index 59273b324ae..bdbe85a67dd 100644
--- a/sormas-api/src/main/resources/validations_ne-NP.properties
+++ b/sormas-api/src/main/resources/validations_ne-NP.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_nl-NL.properties b/sormas-api/src/main/resources/validations_nl-NL.properties
index 59273b324ae..bdbe85a67dd 100644
--- a/sormas-api/src/main/resources/validations_nl-NL.properties
+++ b/sormas-api/src/main/resources/validations_nl-NL.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_no-NO.properties b/sormas-api/src/main/resources/validations_no-NO.properties
index 59273b324ae..bdbe85a67dd 100644
--- a/sormas-api/src/main/resources/validations_no-NO.properties
+++ b/sormas-api/src/main/resources/validations_no-NO.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_pl-PL.properties b/sormas-api/src/main/resources/validations_pl-PL.properties
index 3bdf9615a1e..aa1ccc8f344 100644
--- a/sormas-api/src/main/resources/validations_pl-PL.properties
+++ b/sormas-api/src/main/resources/validations_pl-PL.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_ps-AF.properties b/sormas-api/src/main/resources/validations_ps-AF.properties
index 59273b324ae..bdbe85a67dd 100644
--- a/sormas-api/src/main/resources/validations_ps-AF.properties
+++ b/sormas-api/src/main/resources/validations_ps-AF.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_pt-PT.properties b/sormas-api/src/main/resources/validations_pt-PT.properties
index 59273b324ae..bdbe85a67dd 100644
--- a/sormas-api/src/main/resources/validations_pt-PT.properties
+++ b/sormas-api/src/main/resources/validations_pt-PT.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_ro-RO.properties b/sormas-api/src/main/resources/validations_ro-RO.properties
index 59273b324ae..bdbe85a67dd 100644
--- a/sormas-api/src/main/resources/validations_ro-RO.properties
+++ b/sormas-api/src/main/resources/validations_ro-RO.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_ru-RU.properties b/sormas-api/src/main/resources/validations_ru-RU.properties
index c3bb584481e..6f4633f0b0c 100644
--- a/sormas-api/src/main/resources/validations_ru-RU.properties
+++ b/sormas-api/src/main/resources/validations_ru-RU.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_sv-SE.properties b/sormas-api/src/main/resources/validations_sv-SE.properties
index 59273b324ae..bdbe85a67dd 100644
--- a/sormas-api/src/main/resources/validations_sv-SE.properties
+++ b/sormas-api/src/main/resources/validations_sv-SE.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_sw-KE.properties b/sormas-api/src/main/resources/validations_sw-KE.properties
index 59273b324ae..bdbe85a67dd 100644
--- a/sormas-api/src/main/resources/validations_sw-KE.properties
+++ b/sormas-api/src/main/resources/validations_sw-KE.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_tr-TR.properties b/sormas-api/src/main/resources/validations_tr-TR.properties
index 59273b324ae..bdbe85a67dd 100644
--- a/sormas-api/src/main/resources/validations_tr-TR.properties
+++ b/sormas-api/src/main/resources/validations_tr-TR.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_uk-UA.properties b/sormas-api/src/main/resources/validations_uk-UA.properties
index 59273b324ae..bdbe85a67dd 100644
--- a/sormas-api/src/main/resources/validations_uk-UA.properties
+++ b/sormas-api/src/main/resources/validations_uk-UA.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-api/src/main/resources/validations_ur-PK.properties b/sormas-api/src/main/resources/validations_ur-PK.properties
index 9858bb4f94a..cf0d9cb78aa 100644
--- a/sormas-api/src/main/resources/validations_ur-PK.properties
+++ b/sormas-api/src/main/resources/validations_ur-PK.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=دورہ، علامات شروع ہونے سے پہلے
visitDate = آپ کو دورہ کی تاریخ بتانی ہوگی۔
visitSymptoms = آپ کو دورے کے لیے علامات بتانا ہوں گی۔
visitStatus = آپ کو دورہ کے لیے حالت بتانا ہوگا۔
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = براہ مہربانی یقینی بنائیں کہ عمر کا یہ تخمینہ درست ہے۔ اگر قابل اطلاق ہو تو اسے 150 سے کم میں تبدیل کریں۔
validPointOfEntry = آپ کو داخلے کی ایک درست جگہ بتانا ہوگا
exportNoNameSpecified = براہ مہربانی اپنی ايکسپورٹ کنفیگریشن کے لیے نام ٹائپ کریں
diff --git a/sormas-api/src/main/resources/validations_zh-CN.properties b/sormas-api/src/main/resources/validations_zh-CN.properties
index 1cffe32fc7e..27e5c5e37b0 100644
--- a/sormas-api/src/main/resources/validations_zh-CN.properties
+++ b/sormas-api/src/main/resources/validations_zh-CN.properties
@@ -144,6 +144,8 @@ visitBeforeSymptomsOnSet=The visit cannot be more than %d days before the sympto
visitDate = You have to specify a visit date.
visitSymptoms = You have to specify symptoms for a visit.
visitStatus = You have to specify the status for a visit.
+environmentName = You have to specify an environment name
+environmentMedia = You have to specify the environment media
softApproximateAgeTooHigh = Please make sure that this approximate age value is correct; If applicable, change it to a value lower than 150.
validPointOfEntry = You have to specify a valid point of entry
exportNoNameSpecified = Please type in a name for your export configuration
diff --git a/sormas-app/pom.xml b/sormas-app/pom.xml
index 24ee76cc1e0..a6a4fe363f7 100644
--- a/sormas-app/pom.xml
+++ b/sormas-app/pom.xml
@@ -3,7 +3,7 @@
sormas-base
de.symeda.sormas
- 1.89.0-SNAPSHOT
+ 1.90.0-SNAPSHOT
../sormas-base
4.0.0
diff --git a/sormas-backend/pom.xml b/sormas-backend/pom.xml
index 176828ed37f..e6cf068f3cc 100644
--- a/sormas-backend/pom.xml
+++ b/sormas-backend/pom.xml
@@ -3,7 +3,7 @@
sormas-base
de.symeda.sormas
- 1.89.0-SNAPSHOT
+ 1.90.0-SNAPSHOT
../sormas-base
4.0.0
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 3d7142e94c8..e101b79a75b 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
@@ -2819,6 +2819,7 @@ public void deleteCaseInExternalSurveillanceTool(Case caze) throws ExternalSurve
@Override
@RightsAllowed(UserRight._CASE_ARCHIVE)
+ @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public ProcessedEntity archive(String entityUuid, Date endOfProcessingDate, boolean includeContacts) {
ProcessedEntity processedEntity = super.archive(entityUuid, endOfProcessingDate);
if (includeContacts) {
@@ -2843,6 +2844,7 @@ public List archive(List entityUuids, boolean includeCo
@Override
@RightsAllowed(UserRight._CASE_ARCHIVE)
+ @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public ProcessedEntity dearchive(String entityUuid, String dearchiveReason, boolean includeContacts) {
ProcessedEntity processedEntity = dearchive(Collections.singletonList(entityUuid), dearchiveReason, includeContacts).get(0);
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 6006b55e1e9..85e89768303 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
@@ -64,7 +64,6 @@
import de.symeda.sormas.api.RequestContextHolder;
import de.symeda.sormas.api.caze.CaseClassification;
import de.symeda.sormas.api.caze.CaseCriteria;
-import de.symeda.sormas.api.caze.CaseDataDto;
import de.symeda.sormas.api.caze.CaseListEntryDto;
import de.symeda.sormas.api.caze.CaseLogic;
import de.symeda.sormas.api.caze.CaseMergeIndexDto;
@@ -1155,7 +1154,7 @@ public List dearchive(List entityUuids, String dearchiv
private List updateArchiveFlagInExternalSurveillanceTool(List entityUuids, boolean archived) {
List processedEntities = new ArrayList<>();
- List sharedCaseUuids = getEligibleUuidsForSharingWithExternalSurveillanceTool(entityUuids);
+ List sharedCaseUuids = getUuidsForSharingWithExternalSurvTool(entityUuids);
if (!sharedCaseUuids.isEmpty()) {
processedEntities = externalSurveillanceToolGatewayFacade.sendCasesInternal(sharedCaseUuids, archived);
}
@@ -1163,18 +1162,17 @@ private List updateArchiveFlagInExternalSurveillanceTool(List getEligibleUuidsForSharingWithExternalSurveillanceTool(List entityUuids) {
+ private List getUuidsForSharingWithExternalSurvTool(List entityUuids) {
List sharedCaseUuids = new ArrayList<>();
- List uuidsAllowedToBeShared = getEntityUuidsAllowedToBeShared(entityUuids);
- if (!uuidsAllowedToBeShared.isEmpty()) {
- sharedCaseUuids = getSharedCaseUuids(uuidsAllowedToBeShared);
+ List idsAllowedToBeShared = getEntityIdsAllowedToBeShared(entityUuids);
+ if (!idsAllowedToBeShared.isEmpty()) {
+ sharedCaseUuids = getSharedCaseUuids(idsAllowedToBeShared);
}
return sharedCaseUuids;
}
- public List getSharedCaseUuids(List entityUuids) {
- List caseIds = getCaseIds(entityUuids);
+ private List getSharedCaseUuids(List caseIds) {
List sharedCaseUuids = new ArrayList<>();
List caseShareInfos =
externalShareInfoService.getShareCountAndLatestDate(caseIds, ExternalShareInfo.CAZE);
@@ -1193,11 +1191,18 @@ public List getCaseIds(List entityUuids) {
return caseIds;
}
- public List getEntityUuidsAllowedToBeShared(List entityUuids) {
- List casesAllowedToBeShare =
- caseFacade.getByUuids(entityUuids).stream().filter(c -> !c.isDontShareWithReportingTool()).collect(Collectors.toList());
+ private List getEntityIdsAllowedToBeShared(List entityUuids) {
+ if (entityUuids == null || entityUuids.isEmpty()) {
+ return Collections.emptyList();
+ }
- return casesAllowedToBeShare.stream().map(CaseDataDto::getUuid).collect(Collectors.toList());
+ CriteriaBuilder cb = em.getCriteriaBuilder();
+ CriteriaQuery cq = cb.createQuery(Long.class);
+ Root from = cq.from(Case.class);
+ cq.where(from.get(Case.UUID).in(entityUuids), cb.isFalse(from.get(Case.DONT_SHARE_WITH_REPORTING_TOOL)));
+ cq.select(from.get(Case.ID));
+
+ return em.createQuery(cq).getResultList();
}
@Override
diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/Environment.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/Environment.java
index 112f40b2b4e..97ee9fc0fa1 100644
--- a/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/Environment.java
+++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/Environment.java
@@ -4,7 +4,9 @@
import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_DEFAULT;
import java.util.Date;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
@@ -14,6 +16,7 @@
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@@ -26,6 +29,7 @@
import de.symeda.sormas.api.environment.WaterType;
import de.symeda.sormas.api.environment.WaterUse;
import de.symeda.sormas.backend.common.CoreAdo;
+import de.symeda.sormas.backend.environment.environmentsample.EnvironmentSample;
import de.symeda.sormas.backend.location.Location;
import de.symeda.sormas.backend.user.User;
import de.symeda.sormas.backend.util.ModelConstants;
@@ -67,6 +71,7 @@ public class Environment extends CoreAdo {
private Map waterUse;
private String otherWaterUse;
private Location location;
+ private Set environmentSamples = new HashSet<>();
@Temporal(TemporalType.TIMESTAMP)
@Column(nullable = false)
@@ -210,4 +215,13 @@ public Location getLocation() {
public void setLocation(Location location) {
this.location = location;
}
+
+ @OneToMany(mappedBy = EnvironmentSample.ENVIRONMENT, fetch = FetchType.LAZY)
+ public Set getEnvironmentSamples() {
+ return environmentSamples;
+ }
+
+ public void setEnvironmentSamples(Set environmentSamples) {
+ this.environmentSamples = environmentSamples;
+ }
}
diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/EnvironmentImportFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/EnvironmentImportFacadeEjb.java
index 1d2aed4232a..a41e8cf4939 100644
--- a/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/EnvironmentImportFacadeEjb.java
+++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/EnvironmentImportFacadeEjb.java
@@ -39,11 +39,13 @@
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
+import de.symeda.sormas.api.environment.EnvironmentCriteria;
import de.symeda.sormas.api.environment.EnvironmentDto;
import de.symeda.sormas.api.environment.EnvironmentImportFacade;
import de.symeda.sormas.api.environment.WaterUse;
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.i18n.Validations;
import de.symeda.sormas.api.importexport.ImportCellData;
import de.symeda.sormas.api.importexport.ImportErrorException;
@@ -52,6 +54,7 @@
import de.symeda.sormas.api.infrastructure.community.CommunityReferenceDto;
import de.symeda.sormas.api.infrastructure.district.DistrictReferenceDto;
import de.symeda.sormas.api.infrastructure.facility.FacilityReferenceDto;
+import de.symeda.sormas.api.location.LocationDto;
import de.symeda.sormas.api.user.UserRight;
import de.symeda.sormas.api.utils.DataHelper;
import de.symeda.sormas.api.utils.DateHelper;
@@ -75,6 +78,8 @@ public class EnvironmentImportFacadeEjb implements EnvironmentImportFacade {
@EJB
private EnvironmentFacadeEjbLocal environmentFacade;
@EJB
+ private EnvironmentService environmentService;
+ @EJB
private ImportFacadeEjbLocal importFacade;
@EJB
private DistrictFacadeEjb.DistrictFacadeEjbLocal districtFacade;
@@ -90,6 +95,7 @@ public ImportLineResultDto importEnvironmentData(
String[] entityProperties,
String[][] entityPropertyPaths,
boolean ignoreEmptyEntries) {
+
// Check whether the new line has the same length as the header line
if (values.length > entityProperties.length) {
return ImportLineResultDto.errorResult(I18nProperties.getValidationError(Validations.importLineTooLong));
@@ -98,6 +104,7 @@ public ImportLineResultDto importEnvironmentData(
final EnvironmentDto environment = EnvironmentDto.build(userFacade.getCurrentUser());
ImportLineResultDto importResult =
buildEnvironment(values, entityClasses, entityPropertyPaths, ignoreEmptyEntries, environment);
+
if (importResult.isError()) {
return importResult;
}
@@ -105,6 +112,21 @@ public ImportLineResultDto importEnvironmentData(
ImportLineResultDto validationResult = validateEnvironment(environment);
if (validationResult.isError()) {
return validationResult;
+ } else {
+ LocationDto environmentLocation = environment.getLocation();
+ EnvironmentCriteria criteria = new EnvironmentCriteria().country(environmentLocation.getCountry())
+ .region(environmentLocation.getRegion())
+ .district(environmentLocation.getDistrict())
+ .gpsLat(environmentLocation.getLatitude())
+ .gpsLon(environmentLocation.getLongitude())
+ .environmentMedia(environment.getEnvironmentMedia())
+ .externalId(environment.getExternalId());
+ String similarEnvironmentUuid = environmentService.getSimilarEnvironmentUuid(criteria);
+ if (similarEnvironmentUuid != null) {
+ return ImportLineResultDto.duplicateResult(
+ environment,
+ String.format(I18nProperties.getString(Strings.messageDuplicateEnvironmentFound), similarEnvironmentUuid));
+ }
}
return saveEnvironment(environment);
@@ -117,7 +139,7 @@ private ImportLineResultDto buildEnvironment(
boolean ignoreEmptyEntries,
EnvironmentDto environment) {
- return (ImportLineResultDto) insertRowIntoData(values, entityClasses, entityPropertyPaths, ignoreEmptyEntries, (cellData) -> {
+ return insertRowIntoData(values, entityClasses, entityPropertyPaths, ignoreEmptyEntries, (cellData) -> {
try {
if (!StringUtils.isEmpty(cellData.getValue())) {
insertColumnEntryIntoData(environment, cellData.getValue(), cellData.getEntityPropertyPath());
diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/EnvironmentJoins.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/EnvironmentJoins.java
index a25a3388ee0..d110f17207f 100644
--- a/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/EnvironmentJoins.java
+++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/environment/EnvironmentJoins.java
@@ -6,6 +6,7 @@
import de.symeda.sormas.backend.common.QueryJoins;
import de.symeda.sormas.backend.infrastructure.community.Community;
+import de.symeda.sormas.backend.infrastructure.country.Country;
import de.symeda.sormas.backend.infrastructure.district.District;
import de.symeda.sormas.backend.infrastructure.region.Region;
import de.symeda.sormas.backend.location.Location;
@@ -39,6 +40,10 @@ public void setLocationJoins(LocationJoins locationJoins) {
this.locationJoins = locationJoins;
}
+ public Join getCountry() {
+ return getLocationJoins().getCountry();
+ }
+
public Join getRegion() {
return getLocationJoins().getRegion();
}
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 ef3f952ba68..69f8b6a3ef2 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
@@ -19,8 +19,12 @@
import de.symeda.sormas.api.EntityRelevanceStatus;
import de.symeda.sormas.api.RequestContextHolder;
import de.symeda.sormas.api.common.DeletableEntityType;
+import de.symeda.sormas.api.common.DeletionDetails;
import de.symeda.sormas.api.environment.EnvironmentCriteria;
import de.symeda.sormas.api.event.EventCriteria;
+import de.symeda.sormas.api.infrastructure.country.CountryReferenceDto;
+import de.symeda.sormas.api.infrastructure.district.DistrictReferenceDto;
+import de.symeda.sormas.api.infrastructure.region.RegionReferenceDto;
import de.symeda.sormas.api.user.JurisdictionLevel;
import de.symeda.sormas.api.utils.DataHelper;
import de.symeda.sormas.backend.common.AbstractCoreAdoService;
@@ -28,7 +32,9 @@
import de.symeda.sormas.backend.common.ChangeDateFilterBuilder;
import de.symeda.sormas.backend.common.CriteriaBuilderHelper;
import de.symeda.sormas.backend.common.DeletableAdo;
+import de.symeda.sormas.backend.environment.environmentsample.EnvironmentSampleService;
import de.symeda.sormas.backend.infrastructure.community.Community;
+import de.symeda.sormas.backend.infrastructure.country.Country;
import de.symeda.sormas.backend.infrastructure.district.District;
import de.symeda.sormas.backend.infrastructure.region.Region;
import de.symeda.sormas.backend.location.Location;
@@ -39,13 +45,31 @@
@LocalBean
public class EnvironmentService extends AbstractCoreAdoService {
+ private static final double ALLOWED_GPS_SIMILARITY_VARIANCE = 0.2d;
+
@EJB
private UserService userService;
+ @EJB
+ private EnvironmentSampleService environmentSampleService;
public EnvironmentService() {
super(Environment.class, DeletableEntityType.ENVIRONMENT);
}
+ public String getSimilarEnvironmentUuid(EnvironmentCriteria criteria) {
+
+ CriteriaBuilder cb = em.getCriteriaBuilder();
+ CriteriaQuery cq = cb.createQuery(String.class);
+ Root root = cq.from(Environment.class);
+ EnvironmentQueryContext queryContext = new EnvironmentQueryContext(cb, cq, root);
+
+ cq.select(root.get(Environment.UUID));
+ cq.where(buildSimilarityFilters(criteria, cb, root, queryContext));
+
+ List results = em.createQuery(cq).getResultList();
+ return results.isEmpty() ? null : results.get(0);
+ }
+
@Override
protected Predicate createUserFilterInternal(CriteriaBuilder cb, CriteriaQuery cq, From, Environment> from) {
return createUserFilter(new EnvironmentQueryContext(cb, cq, from));
@@ -249,6 +273,79 @@ public Predicate buildCriteriaFilter(EnvironmentCriteria environmentCriteria, En
return filter;
}
+ private Predicate buildSimilarityFilters(
+ EnvironmentCriteria criteria,
+ CriteriaBuilder cb,
+ Root root,
+ EnvironmentQueryContext queryContext) {
+
+ // Environment media and GPS coordinates must always be present for environments to be considered as duplicates
+ if (criteria.getEnvironmentMedia() == null || criteria.getGpsLat() == null || criteria.getGpsLon() == null) {
+ return cb.disjunction();
+ }
+
+ EnvironmentJoins joins = queryContext.getJoins();
+
+ Predicate filter = createDefaultFilter(cb, root);
+
+ // Environment media
+ filter = CriteriaBuilderHelper.and(
+ cb,
+ filter,
+ cb.and(
+ cb.isNotNull(root.get(Environment.ENVIRONMENT_MEDIA)),
+ cb.equal(root.get(Environment.ENVIRONMENT_MEDIA), criteria.getEnvironmentMedia())));
+
+ // GPS coordinates
+ filter = CriteriaBuilderHelper.and(
+ cb,
+ filter,
+ cb.and(
+ cb.isNotNull(joins.getLocation().get(Location.LATITUDE)),
+ cb.greaterThanOrEqualTo(joins.getLocation().get(Location.LATITUDE), criteria.getGpsLat() - ALLOWED_GPS_SIMILARITY_VARIANCE),
+ cb.lessThanOrEqualTo(joins.getLocation().get(Location.LATITUDE), criteria.getGpsLat() + ALLOWED_GPS_SIMILARITY_VARIANCE)));
+ filter = CriteriaBuilderHelper.and(
+ cb,
+ filter,
+ cb.and(
+ cb.isNotNull(joins.getLocation().get(Location.LONGITUDE)),
+ cb.greaterThanOrEqualTo(joins.getLocation().get(Location.LONGITUDE), criteria.getGpsLon() - ALLOWED_GPS_SIMILARITY_VARIANCE),
+ cb.lessThanOrEqualTo(joins.getLocation().get(Location.LONGITUDE), criteria.getGpsLon() + ALLOWED_GPS_SIMILARITY_VARIANCE)));
+
+ CountryReferenceDto criteriaCountry = criteria.getCountry();
+ RegionReferenceDto criteriaRegion = criteria.getRegion();
+ DistrictReferenceDto criteriaDistrict = criteria.getDistrict();
+ // Country
+ if (criteriaCountry != null) {
+ filter = CriteriaBuilderHelper.and(
+ cb,
+ filter,
+ cb.or(cb.isNull(joins.getCountry()), cb.equal(joins.getCountry().get(Country.UUID), criteria.getCountry().getUuid())));
+ }
+ // Region
+ if (criteriaRegion != null) {
+ filter = CriteriaBuilderHelper
+ .and(cb, filter, cb.or(cb.isNull(joins.getRegion()), cb.equal(joins.getRegion().get(Region.UUID), criteria.getRegion().getUuid())));
+ }
+ // District
+ if (criteriaDistrict != null) {
+ filter = CriteriaBuilderHelper.and(
+ cb,
+ filter,
+ cb.or(cb.isNull(joins.getDistrict()), cb.equal(joins.getDistrict().get(District.UUID), criteria.getDistrict().getUuid())));
+ }
+
+ // External ID
+ if (StringUtils.isNotBlank(criteria.getExternalId())) {
+ filter = CriteriaBuilderHelper.or(
+ cb,
+ cb.and(cb.isNull(root.get(Environment.EXTERNAL_ID)), filter),
+ cb.equal(root.get(Environment.EXTERNAL_ID), criteria.getExternalId()));
+ }
+
+ return filter;
+ }
+
/**
* Creates a default filter that should be used as the basis of queries that do not use {@link EventCriteria}.
* This essentially removes {@link DeletableAdo#isDeleted()} events from the queries.
@@ -308,4 +405,10 @@ public List getAllActiveUuids(User user) {
return em.createQuery(cq).getResultList();
}
+
+ @Override
+ public void delete(Environment environment, DeletionDetails deletionDetails) {
+ environment.getEnvironmentSamples().forEach(s -> environmentSampleService.delete(s, deletionDetails));
+ super.delete(environment, deletionDetails);
+ }
}
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 3e791ac5eda..5965685f3a0 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
@@ -1049,6 +1049,7 @@ public List getArchivedUuidsSince(Date since) {
@Override
@RightsAllowed(UserRight._EVENT_ARCHIVE)
+ @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public ProcessedEntity archive(String eventUuid, Date endOfProcessingDate) {
ProcessedEntity processedEntity = super.archive(eventUuid, endOfProcessingDate);
List eventParticipantList = eventParticipantService.getAllUuidsByEventUuids(Collections.singletonList(eventUuid));
@@ -1069,6 +1070,7 @@ public List archive(List eventUuids) {
@Override
@RightsAllowed(UserRight._EVENT_ARCHIVE)
+ @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public ProcessedEntity dearchive(String entityUuid, String dearchiveReason) {
ProcessedEntity processedEntity = dearchive(Collections.singletonList(entityUuid), dearchiveReason).get(0);
diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/feature/FeatureConfigurationService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/feature/FeatureConfigurationService.java
index f5d3e5e913a..049570c7570 100644
--- a/sormas-backend/src/main/java/de/symeda/sormas/backend/feature/FeatureConfigurationService.java
+++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/feature/FeatureConfigurationService.java
@@ -1,6 +1,8 @@
package de.symeda.sormas.backend.feature;
+import java.util.Arrays;
import java.util.Date;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
@@ -15,11 +17,13 @@
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
+import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.ArrayUtils;
import de.symeda.sormas.api.common.DeletableEntityType;
import de.symeda.sormas.api.feature.FeatureConfigurationCriteria;
import de.symeda.sormas.api.feature.FeatureType;
+import de.symeda.sormas.api.feature.FeatureTypeProperty;
import de.symeda.sormas.backend.common.AbstractDomainObject;
import de.symeda.sormas.backend.common.AdoServiceWithUserFilterAndJurisdiction;
import de.symeda.sormas.backend.common.CriteriaBuilderHelper;
@@ -141,36 +145,60 @@ public void createMissingFeatureConfigurations() {
}
private void createFeatureConfiguration(FeatureType featureType, DeletableEntityType deletableEntityType) {
+
FeatureConfiguration configuration = FeatureConfiguration.build(featureType, featureType.isEnabledDefault());
configuration.setEntityType(deletableEntityType);
configuration.setProperties(featureType.getSupportedPropertyDefaults());
ensurePersisted(configuration);
}
+ /**
+ * Disables features for which a dependent feature is disabled, and automatically adds new feature type properties.
+ */
public void updateFeatureConfigurations() {
Map configs = getServerFeatureConfigurations();
- FeatureType.getAllServerFeatures().forEach(featureType -> {
- if (featureType.isDependent()) {
+ Arrays.stream(FeatureType.values()).forEach(featureType -> {
+ FeatureConfiguration configuration = configs.get(featureType);
+ boolean persistingNeeded = false;
+
+ if (featureType.isServerFeature() && featureType.isDependent()) {
boolean hasEnabledDependentFeature = hasEnabledDependentFeature(featureType, configs);
if (!hasEnabledDependentFeature) {
- FeatureConfiguration configuration = configs.get(featureType);
configuration.setEnabled(false);
- ensurePersisted(configuration);
+ persistingNeeded = true;
+ }
+ }
+
+ Map supportedPropertyDefaults = featureType.getSupportedPropertyDefaults();
+ if (MapUtils.isNotEmpty(supportedPropertyDefaults)) {
+ if (configuration.getProperties() == null || !supportedPropertyDefaults.keySet().equals(configuration.getProperties().keySet())) {
+ if (configuration.getProperties() == null) {
+ configuration.setProperties(new HashMap<>());
+ }
+ Map configProperties = configuration.getProperties();
+ supportedPropertyDefaults.keySet().forEach(property -> {
+ if (!configProperties.containsKey(property)) {
+ configProperties.put(property, supportedPropertyDefaults.get(property));
+ }
+ });
+ persistingNeeded = true;
}
}
+
+ if (persistingNeeded) {
+ ensurePersisted(configuration);
+ }
});
}
private Map getServerFeatureConfigurations() {
List featureConfigurations = getAll();
- Map configurationsMap = featureConfigurations.stream()
+ return featureConfigurations.stream()
.filter(e -> e.getFeatureType().isServerFeature())
// In case a serverFeature happens not to be unique in the database, take the last one
.collect(Collectors.toMap(FeatureConfiguration::getFeatureType, Function.identity(), (e1, e2) -> e2));
-
- return configurationsMap;
}
private boolean hasEnabledDependentFeature(FeatureType featureType, Map featureConfigurationMap) {
diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/location/LocationJoins.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/location/LocationJoins.java
index 8f708e935fe..42a14fc3639 100644
--- a/sormas-backend/src/main/java/de/symeda/sormas/backend/location/LocationJoins.java
+++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/location/LocationJoins.java
@@ -21,12 +21,14 @@
import de.symeda.sormas.backend.common.QueryJoins;
import de.symeda.sormas.backend.infrastructure.community.Community;
+import de.symeda.sormas.backend.infrastructure.country.Country;
import de.symeda.sormas.backend.infrastructure.district.District;
import de.symeda.sormas.backend.infrastructure.facility.Facility;
import de.symeda.sormas.backend.infrastructure.region.Region;
public class LocationJoins extends QueryJoins {
+ private Join country;
private Join region;
private Join district;
private Join community;
@@ -36,6 +38,14 @@ public LocationJoins(From, Location> root) {
super(root);
}
+ public Join getCountry() {
+ return getOrCreate(country, Location.COUNTRY, JoinType.LEFT, this::setCountry);
+ }
+
+ private void setCountry(Join country) {
+ this.country = country;
+ }
+
public Join getRegion() {
return getOrCreate(region, Location.REGION, JoinType.LEFT, this::setRegion);
}
@@ -67,4 +77,5 @@ public Join getFacility() {
private void setFacility(Join facility) {
this.facility = facility;
}
+
}
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 8e80b30b520..a36f5d5c8df 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
@@ -273,6 +273,11 @@ public UserDto createUser(RDCF rdcf, UserRoleReferenceDto... roles) {
roles);
}
+ public UserDto createUser(RDCF rdcf, DefaultUserRole defaultUserRole) {
+ UserRoleReferenceDto userRole = getUserRoleReference(defaultUserRole);
+ return createUser(rdcf.region.getUuid(), rdcf.district.getUuid(), rdcf.facility.getUuid(), userRole.getCaption(), "User", userRole);
+ }
+
public UserDto createUser(RDCF rdcf, String firstName, String lastName, UserRoleReferenceDto... roles) {
return createUser(
rdcf.region.getUuid(),
diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseExternalSurveillanceToolTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseExternalSurveillanceToolTest.java
new file mode 100644
index 00000000000..b0d6b04d179
--- /dev/null
+++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseExternalSurveillanceToolTest.java
@@ -0,0 +1,123 @@
+/*
+ * 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 de.symeda.sormas.backend.caze;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.containing;
+import static com.github.tomakehurst.wiremock.client.WireMock.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.Matchers.hasSize;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.http.HttpStatus;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
+import com.github.tomakehurst.wiremock.junit5.WireMockTest;
+
+import de.symeda.sormas.api.caze.CaseDataDto;
+import de.symeda.sormas.api.common.progress.ProcessedEntity;
+import de.symeda.sormas.api.common.progress.ProcessedEntityStatus;
+import de.symeda.sormas.api.share.ExternalShareStatus;
+import de.symeda.sormas.api.user.DefaultUserRole;
+import de.symeda.sormas.api.user.UserReferenceDto;
+import de.symeda.sormas.backend.AbstractBeanTest;
+import de.symeda.sormas.backend.MockProducer;
+import de.symeda.sormas.backend.TestDataCreator;
+
+@WireMockTest(httpPort = 8888)
+public class CaseExternalSurveillanceToolTest extends AbstractBeanTest {
+
+ private UserReferenceDto reportingUser;
+ private TestDataCreator.RDCF rdcf;
+
+ @Override
+ public void init() {
+ super.init();
+ rdcf = creator.createRDCF();
+ reportingUser = creator.createUser(rdcf, DefaultUserRole.SURVEILLANCE_OFFICER).toReference();
+ }
+
+ @BeforeEach
+ public void setup(WireMockRuntimeInfo wireMockRuntime) {
+ configureExternalSurvToolUrlForWireMock(wireMockRuntime);
+ }
+
+ @AfterEach
+ public void teardown() {
+ clearExternalSurvToolUrlForWireMock();
+ }
+
+ @Test
+ public void testArchiveCasesSharedWithExternalSurvTool() {
+ CaseDataDto caseNotShared = creator.createCase(reportingUser, creator.createPerson().toReference(), rdcf);
+
+ CaseDataDto caseShared = creator.createCase(reportingUser, creator.createPerson().toReference(), rdcf);
+ creator.createExternalShareInfo(caseShared.toReference(), reportingUser, ExternalShareStatus.SHARED, null);
+
+ CaseDataDto caseMarkedToNotShare =
+ creator.createCase(reportingUser, creator.createPerson().toReference(), rdcf, c -> c.setDontShareWithReportingTool(true));
+
+ CaseDataDto caseSharedThenMarkedToNotShare =
+ creator.createCase(reportingUser, creator.createPerson().toReference(), rdcf, c -> c.setDontShareWithReportingTool(true));
+ creator.createExternalShareInfo(caseSharedThenMarkedToNotShare.toReference(), reportingUser, ExternalShareStatus.SHARED, null);
+
+ CaseDataDto caseSharedThenDeletedInExternalSurvTool = creator.createCase(reportingUser, creator.createPerson().toReference(), rdcf);
+ creator.createExternalShareInfo(caseSharedThenDeletedInExternalSurvTool.toReference(), reportingUser, ExternalShareStatus.SHARED, null);
+ creator.createExternalShareInfo(caseSharedThenDeletedInExternalSurvTool.toReference(), reportingUser, ExternalShareStatus.DELETED, null);
+
+ CaseDataDto caseReShared = creator.createCase(reportingUser, creator.createPerson().toReference(), rdcf);
+ creator.createExternalShareInfo(caseReShared.toReference(), reportingUser, ExternalShareStatus.SHARED, null);
+ creator.createExternalShareInfo(caseReShared.toReference(), reportingUser, ExternalShareStatus.DELETED, null);
+ creator.createExternalShareInfo(caseReShared.toReference(), reportingUser, ExternalShareStatus.SHARED, null);
+
+ stubFor(
+ post(urlEqualTo("/export"))
+ .withRequestBody(containing("caseUuids").and(containing(caseShared.getUuid())).and(containing(caseReShared.getUuid())))
+ .willReturn(aResponse().withStatus(HttpStatus.SC_OK)));
+
+ List result = getCaseFacade().archive(
+ Arrays.asList(
+ caseNotShared.getUuid(),
+ caseShared.getUuid(),
+ caseMarkedToNotShare.getUuid(),
+ caseSharedThenMarkedToNotShare.getUuid(),
+ caseSharedThenDeletedInExternalSurvTool.getUuid(),
+ caseReShared.getUuid()));
+
+ assertThat(result, hasSize(6));
+ assertThat(
+ result.stream().map(ProcessedEntity::getProcessedEntityStatus).collect(Collectors.toSet()),
+ containsInAnyOrder(ProcessedEntityStatus.SUCCESS));
+ }
+
+ private void configureExternalSurvToolUrlForWireMock(WireMockRuntimeInfo wireMockRuntime) {
+ MockProducer.getProperties().setProperty("survnet.url", String.format("http://localhost:%s", wireMockRuntime.getHttpPort()));
+ }
+
+ private void clearExternalSurvToolUrlForWireMock() {
+ MockProducer.getProperties().setProperty("survnet.url", "");
+ }
+
+}
diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/environment/EnvironmentServiceTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/environment/EnvironmentServiceTest.java
new file mode 100644
index 00000000000..8ef5dc96441
--- /dev/null
+++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/environment/EnvironmentServiceTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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 de.symeda.sormas.backend.environment;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+import org.junit.jupiter.api.Test;
+
+import de.symeda.sormas.api.environment.EnvironmentCriteria;
+import de.symeda.sormas.api.environment.EnvironmentDto;
+import de.symeda.sormas.api.environment.EnvironmentMedia;
+import de.symeda.sormas.backend.AbstractBeanTest;
+import de.symeda.sormas.backend.TestDataCreator.RDCF;
+
+public class EnvironmentServiceTest extends AbstractBeanTest {
+
+ @Test
+ public void testGetSimilarEnvironmentUuid() {
+
+ RDCF rdcf = creator.createRDCF();
+ RDCF rdcf2 = creator.createRDCF("Region2", "District2", "Community2", "Facility2");
+
+ EnvironmentDto environment1 = creator.createEnvironment("Environment1", EnvironmentMedia.AIR, nationalAdmin.toReference(), rdcf, e -> {
+ e.getLocation().setLatitude(-80D);
+ e.getLocation().setLongitude(170D);
+ e.setExternalId("12345");
+ });
+ EnvironmentDto environment2 = creator.createEnvironment("Environment2", EnvironmentMedia.WATER, nationalAdmin.toReference(), rdcf, e -> {
+ e.getLocation().setLatitude(64D);
+ e.getLocation().setLongitude(-92D);
+ });
+
+ EnvironmentCriteria criteria = new EnvironmentCriteria().environmentMedia(EnvironmentMedia.AIR);
+ // GPS coordinates missing from criteria
+ assertNull(getEnvironmentService().getSimilarEnvironmentUuid(criteria));
+ criteria.gpsLat(-80D).gpsLon(170D);
+ // Environment media and GPS coordinates specified
+ assertEquals(environment1.getUuid(), getEnvironmentService().getSimilarEnvironmentUuid(criteria));
+ criteria.setExternalId("678910");
+ // External ID does not match, overrides everything else
+ assertNull(getEnvironmentService().getSimilarEnvironmentUuid(criteria));
+ criteria.externalId("12345").gpsLat(50D).gpsLon(50D).environmentMedia(EnvironmentMedia.WATER);
+ // External ID matches, overrides everything else
+ assertEquals(environment1.getUuid(), getEnvironmentService().getSimilarEnvironmentUuid(criteria));
+ criteria.gpsLat(64D).gpsLon(-92D).externalId(null).region(rdcf2.region).district(rdcf2.district);
+ // Region and district specified for both, but do not match
+ assertNull(getEnvironmentService().getSimilarEnvironmentUuid(criteria));
+ criteria.region(rdcf.region).district(rdcf.district);
+ // Region and district specified for both and matching
+ assertEquals(environment2.getUuid(), getEnvironmentService().getSimilarEnvironmentUuid(criteria));
+ }
+}
diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml
index 8cda7a43557..d2084419ee1 100644
--- a/sormas-base/pom.xml
+++ b/sormas-base/pom.xml
@@ -5,7 +5,7 @@
de.symeda.sormas
sormas-base
pom
- 1.89.0-SNAPSHOT
+ 1.90.0-SNAPSHOT
3.6.3
diff --git a/sormas-cargoserver/pom.xml b/sormas-cargoserver/pom.xml
index 1c7c5505f5a..a2303f9b8af 100644
--- a/sormas-cargoserver/pom.xml
+++ b/sormas-cargoserver/pom.xml
@@ -3,7 +3,7 @@
de.symeda.sormas
sormas-base
- 1.89.0-SNAPSHOT
+ 1.90.0-SNAPSHOT
../sormas-base
diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/aCommonComponents/GeneralActions.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/aCommonComponents/GeneralActions.java
index b405d2171c9..9ecb54eb5a3 100644
--- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/aCommonComponents/GeneralActions.java
+++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/aCommonComponents/GeneralActions.java
@@ -23,4 +23,6 @@
public class GeneralActions {
public static final By READ_ONLY_FIELDS = By.xpath("//*[@aria-disabled='true']");
+ public static final By READ_ONLY_FIELDS_SURVNET_DETAILS =
+ By.cssSelector("[class='v-label v-disabled v-widget v-label-undef-w']");
}
diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/aCommonComponents/GeneralActionsSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/aCommonComponents/GeneralActionsSteps.java
index 6a0d26d2473..eb80b6ee295 100644
--- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/aCommonComponents/GeneralActionsSteps.java
+++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/aCommonComponents/GeneralActionsSteps.java
@@ -19,6 +19,7 @@
package org.sormas.e2etests.steps.web.application.aCommonComponents;
import static org.sormas.e2etests.pages.application.aCommonComponents.GeneralActions.READ_ONLY_FIELDS;
+import static org.sormas.e2etests.pages.application.aCommonComponents.GeneralActions.READ_ONLY_FIELDS_SURVNET_DETAILS;
import static org.sormas.e2etests.pages.application.aCommonComponents.SideCards.*;
import com.github.javafaker.Faker;
@@ -56,6 +57,17 @@ public GeneralActionsSteps(
" text is not present in handover component");
softly.assertAll();
});
+
+ When(
+ "Total number of read only fields in Survnet details section should be {int}",
+ (Integer number) -> {
+ TimeUnit.SECONDS.sleep(3); // waiting for page loaded
+ softly.assertEquals(
+ webDriverHelpers.getNumberOfElements(READ_ONLY_FIELDS_SURVNET_DETAILS),
+ number.intValue(),
+ " text is not present in handover component");
+ softly.assertAll();
+ });
When("I refresh current page", () -> webDriverHelpers.refreshCurrentPage());
}
}
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 1b7035b8c32..86ae3192a13 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
@@ -67,6 +67,20 @@ public SideCardsSteps(
+ webDriverHelpers.getTextFromPresentWebElement(HANDOVER_SIDE_CARD));
softly.assertAll();
});
+
+ When(
+ "I check if handover card not contains {string} shared information",
+ (String information) -> {
+ webDriverHelpers.waitUntilIdentifiedElementIsVisibleAndClickable(HANDOVER_SIDE_CARD);
+ TimeUnit.SECONDS.sleep(3);
+ softly.assertFalse(
+ webDriverHelpers.isElementPresent(checkTextInHandoverSideComponent(information)),
+ information
+ + " text is not present in handover component. Found only "
+ + webDriverHelpers.getTextFromPresentWebElement(HANDOVER_SIDE_CARD));
+ softly.assertAll();
+ });
+
When(
"I check if handover card contains shared with {string} information",
(String environmentIdentifier) -> {
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 7e09b6a49eb..4887e4c3226 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
@@ -3009,6 +3009,25 @@ public EditCaseSteps(
softly.assertAll();
});
+ When(
+ "I check if Follow up until date is ([^\"]*) days before last created API case report date",
+ (Integer days) -> {
+ TimeUnit.SECONDS.sleep(3);
+ String date = webDriverHelpers.getValueFromWebElement(FOLLOW_UP_UNTIL_DATE);
+ softly.assertEquals(
+ DateTimeFormatter.ofPattern("dd.MM.yyyy")
+ .format(
+ apiState
+ .getCreatedCase()
+ .getReportDate()
+ .toInstant()
+ .atZone(ZoneId.systemDefault())
+ .toLocalDate()
+ .minusDays(days)),
+ date);
+ softly.assertAll();
+ });
+
And(
"^I select \"([^\"]*)\" from the infection settings on Edit Case page$",
(String infectionOption) -> {
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 085d8136eb5..ec07bfdb193 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
@@ -461,6 +461,7 @@ public CreateNewSampleSteps(
When(
"^I save the created sample",
() -> {
+ webDriverHelpers.waitUntilIdentifiedElementIsVisibleAndClickable(SAVE_SAMPLE_BUTTON);
webDriverHelpers.clickOnWebElementBySelector(SAVE_SAMPLE_BUTTON);
});
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 6a65a15cb22..a8275f295e0 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
@@ -1912,25 +1912,4 @@ Feature: Case end to end tests
And API: I check that POST call status code is 200
Given I log in as a National User
Then I navigate to the last created case via the url
- And I check if Follow up until date is 14 days after last created API case report date
- When I click on New Sample in German
- Then I create a new Sample with positive test result for DE version
- And I select the German words for Antigen Detection Test as Type of Test in the Create New Sample popup
- And I set date of sample collection to 5 day ago in Sample form
- And I set Final Laboratory Result to "Positiv" on Create new Sample page
- And I save the created sample
- And I check if Follow up until date is 9 days after last created API case report date
- And I navigate to symptoms tab
- When I check Yes Option for Soar Throat on Symptoms tab page
- And I select sore throat option
- And I set date of symptoms to 6 day ago from Symptoms tab
- And I click on save button from Edit Case page
- Then I navigate to the last created case via the url
- And I check if Follow up until date is 8 days after last created API case report date
- When I click on New Sample in German
- Then I create a new Sample with positive test result for DE version
- And I select the German words for Antigen Detection Test as Type of Test in the Create New Sample popup
- And I set date of sample collection to 7 day ago in Sample form
- And I set Final Laboratory Result to "Positiv" on Create new Sample page
- And I save the created sample
- And I check if Follow up until date is 8 days after last created API case report date
\ No newline at end of file
+ And I check if Follow up until date is 14 days after last created API case report date
\ 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 80be0f2e0f6..004e7d78ca7 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
@@ -1276,4 +1276,31 @@ Feature: Sharing cases between environments tests
Then I select German Status Dropdown to Revoked
And I check that Revoked status value is corresponding with entities
And I click on the The Eye Icon located in the Shares Page
- And I click on the shortened case/contact ID to open the case
\ No newline at end of file
+ And I click on the shortened case/contact ID to open the case
+
+ @tmsLink=HSP-6268 @env_s2s_2
+ Scenario: S2S - Share a case which was sent to Survnet
+ Given I log in as a S2S
+ When I click on the Cases button from navbar
+ And I click on the NEW CASE button
+ And I create a new case with specific data using created facility for Survnet DE
+ And I collect uuid of the case
+ And I click on Send to reporting tool button on Edit Case page
+ Then I click on share button
+ And I select organization to share with "s2s_1"
+ 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_1" environment in new driver tab
+ 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
+ And I open the last created case with collected UUID by url on "s2s_1" instance
+ Then I check if editable fields are enabled for the case in view
+ And I check if handover card not contains "Status: Ausstehend" shared information
+ And I check if handover card not contains "Kommentar: shared to be deleted after" shared information
+ When I back to tab number 1
+ And I refresh current page
+ And Total number of read only fields should be 10
+ Then Total number of read only fields in Survnet details section should be 3
\ No newline at end of file
diff --git a/sormas-ear/pom.xml b/sormas-ear/pom.xml
index 1472d34945e..36255e32ee5 100644
--- a/sormas-ear/pom.xml
+++ b/sormas-ear/pom.xml
@@ -3,7 +3,7 @@
de.symeda.sormas
sormas-base
- 1.89.0-SNAPSHOT
+ 1.90.0-SNAPSHOT
../sormas-base
diff --git a/sormas-keycloak-service-provider/pom.xml b/sormas-keycloak-service-provider/pom.xml
index 85d50aff6b2..b82c40aa623 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.89.0-SNAPSHOT
+ 1.90.0-SNAPSHOT
../sormas-base
4.0.0
diff --git a/sormas-rest/pom.xml b/sormas-rest/pom.xml
index 030ef6bb665..7e58c0061d6 100644
--- a/sormas-rest/pom.xml
+++ b/sormas-rest/pom.xml
@@ -3,12 +3,12 @@
de.symeda.sormas
sormas-base
- 1.89.0-SNAPSHOT
+ 1.90.0-SNAPSHOT
../sormas-base
- /sormas-rest
+ sormas-rest
sormas-rest
@@ -119,20 +119,12 @@
${project.artifactId}
-
maven-war-plugin
+ ${warName}
true
-
- src/main/webapp/META-INF
-
- context.xml
-
- /META-INF
- true
-
src/main/webapp
/
diff --git a/sormas-rest/src/main/webapp/META-INF/context.xml b/sormas-rest/src/main/webapp/META-INF/context.xml
deleted file mode 100644
index b6e6646a57d..00000000000
--- a/sormas-rest/src/main/webapp/META-INF/context.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/sormas-rest/swagger.json b/sormas-rest/swagger.json
index fbd69153a34..f16b1b27d3b 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.89.0-SNAPSHOT"
+ "version" : "1.90.0-SNAPSHOT"
},
"servers" : [ {
"url" : "/sormas-rest"
@@ -17707,6 +17707,9 @@
"assignee" : {
"$ref" : "#/components/schemas/UserReferenceDto"
},
+ "automaticProcessingPossible" : {
+ "type" : "boolean"
+ },
"caseReportDate" : {
"type" : "string",
"format" : "date-time"
diff --git a/sormas-rest/swagger.yaml b/sormas-rest/swagger.yaml
index 703324d124a..024b10b8498 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.89.0-SNAPSHOT
+ version: 1.90.0-SNAPSHOT
servers:
- url: /sormas-rest
paths:
@@ -16219,6 +16219,8 @@ components:
properties:
assignee:
$ref: '#/components/schemas/UserReferenceDto'
+ automaticProcessingPossible:
+ type: boolean
caseReportDate:
type: string
format: date-time
diff --git a/sormas-serverlibs/pom.xml b/sormas-serverlibs/pom.xml
index ef2c2dc06c3..d82021a48cc 100644
--- a/sormas-serverlibs/pom.xml
+++ b/sormas-serverlibs/pom.xml
@@ -3,7 +3,7 @@
sormas-base
de.symeda.sormas
- 1.89.0-SNAPSHOT
+ 1.90.0-SNAPSHOT
../sormas-base
4.0.0
diff --git a/sormas-ui/pom.xml b/sormas-ui/pom.xml
index d5033a43e5e..118e407263f 100644
--- a/sormas-ui/pom.xml
+++ b/sormas-ui/pom.xml
@@ -3,7 +3,7 @@
sormas-base
de.symeda.sormas
- 1.89.0-SNAPSHOT
+ 1.90.0-SNAPSHOT
../sormas-base
4.0.0
diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/environment/importer/EnvironmentImporter.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/environment/importer/EnvironmentImporter.java
index 733ef49094e..2a8f5b94e34 100644
--- a/sormas-ui/src/main/java/de/symeda/sormas/ui/environment/importer/EnvironmentImporter.java
+++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/environment/importer/EnvironmentImporter.java
@@ -46,12 +46,16 @@ protected ImportLineResult importDataFromCsvLine(
String[][] entityPropertyPaths,
boolean firstLine)
throws IOException, InvalidColumnException, InterruptedException {
+
ImportLineResultDto importResult =
environmentImportFacade.importEnvironmentData(values, entityClasses, entityProperties, entityPropertyPaths, !firstLine);
if (importResult.isError()) {
writeImportError(values, importResult.getMessage());
return ImportLineResult.ERROR;
+ } else if (importResult.isDuplicate()) {
+ writeImportError(values, importResult.getMessage());
+ return ImportLineResult.DUPLICATE;
}
return ImportLineResult.SUCCESS;
diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageGrid.java
index c655892467b..29b73af62cf 100644
--- a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageGrid.java
+++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageGrid.java
@@ -20,6 +20,7 @@
import java.util.Date;
import java.util.function.Consumer;
+import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import com.vaadin.data.provider.DataProviderListener;
@@ -36,6 +37,7 @@
import com.vaadin.ui.renderers.HtmlRenderer;
import com.vaadin.ui.themes.ValoTheme;
+import de.symeda.sormas.api.CountryHelper;
import de.symeda.sormas.api.FacadeProvider;
import de.symeda.sormas.api.externalmessage.ExternalMessageCriteria;
import de.symeda.sormas.api.externalmessage.ExternalMessageDto;
@@ -94,13 +96,16 @@ public ExternalMessageGrid(ExternalMessageCriteria criteria) {
.setSortable(false);
addComponentColumn(this::buildProcessComponent).setId(COLUMN_PROCESS).setSortable(false);
-
addComponentColumn(this::buildDownloadButton).setId(COLUMN_DOWNLOAD).setSortable(false);
- setColumns(
+ String[] columns = new String[] {
SHOW_MESSAGE,
- ExternalMessageIndexDto.UUID,
- ExternalMessageIndexDto.TYPE,
+ ExternalMessageIndexDto.UUID };
+ if (!FacadeProvider.getConfigFacade().isConfiguredCountry(CountryHelper.COUNTRY_CODE_LUXEMBOURG)) {
+ columns = ArrayUtils.add(columns, ExternalMessageIndexDto.TYPE);
+ }
+ columns = ArrayUtils.addAll(
+ columns,
ExternalMessageIndexDto.MESSAGE_DATE_TIME,
ExternalMessageIndexDto.REPORTER_NAME,
ExternalMessageIndexDto.REPORTER_POSTAL_CODE,
@@ -114,6 +119,7 @@ public ExternalMessageGrid(ExternalMessageCriteria criteria) {
EDIT_ASSIGNEE,
COLUMN_PROCESS,
COLUMN_DOWNLOAD);
+ setColumns(columns);
((Column) getColumn(ExternalMessageIndexDto.UUID)).setRenderer(new UuidRenderer());
((Column) getColumn(ExternalMessageIndexDto.MESSAGE_DATE_TIME))
diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageGridFilterForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageGridFilterForm.java
index a644cf445c7..a9b327ba818 100644
--- a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageGridFilterForm.java
+++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageGridFilterForm.java
@@ -28,6 +28,7 @@
import com.vaadin.v7.ui.Field;
import com.vaadin.v7.ui.TextField;
+import de.symeda.sormas.api.CountryHelper;
import de.symeda.sormas.api.Disease;
import de.symeda.sormas.api.FacadeProvider;
import de.symeda.sormas.api.ReferenceDto;
@@ -97,7 +98,9 @@ protected void addFields() {
assignee.addItems(FacadeProvider.getUserFacade().getUsersByRegionAndRights(user.getRegion(), null, UserRight.EXTERNAL_MESSAGE_PROCESS));
assignee.setNullSelectionAllowed(true);
- addField(ExternalMessageDto.TYPE, ComboBox.class);
+ if (!FacadeProvider.getConfigFacade().isConfiguredCountry(CountryHelper.COUNTRY_CODE_LUXEMBOURG)) {
+ addField(ExternalMessageDto.TYPE, ComboBox.class);
+ }
addField(FieldConfiguration.pixelSized(ExternalMessageCriteria.DISEASE, 140));
addField(FieldConfiguration.pixelSized(CaseDataDto.DISEASE_VARIANT, 140), ComboBox.class);
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 a1892ed036b..5ae2fd47dfa 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
@@ -5,6 +5,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.function.Consumer;
import javax.annotation.Nullable;
@@ -23,11 +24,14 @@
import com.vaadin.ui.themes.ValoTheme;
import com.vaadin.v7.data.Validator;
+import de.symeda.sormas.api.CountryHelper;
import de.symeda.sormas.api.FacadeProvider;
import de.symeda.sormas.api.externalmessage.ExternalMessageCriteria;
import de.symeda.sormas.api.externalmessage.ExternalMessageFetchResult;
import de.symeda.sormas.api.externalmessage.ExternalMessageStatus;
import de.symeda.sormas.api.externalmessage.NewMessagesState;
+import de.symeda.sormas.api.feature.FeatureType;
+import de.symeda.sormas.api.feature.FeatureTypeProperty;
import de.symeda.sormas.api.i18n.Captions;
import de.symeda.sormas.api.i18n.I18nProperties;
import de.symeda.sormas.api.i18n.Strings;
@@ -77,9 +81,11 @@ public ExternalMessagesView() {
ViewModelProviders.of(ExternalMessagesView.class).get(ExternalMessageCriteria.class, criteria);
}
- addHeaderComponent(ButtonHelper.createIconButton(Captions.externalMessageFetch, VaadinIcons.REFRESH, e -> {
- checkForConcurrentEventsAndFetch();
- }, ValoTheme.BUTTON_PRIMARY));
+ if (FacadeProvider.getFeatureConfigurationFacade().isPropertyValueTrue(FeatureType.EXTERNAL_MESSAGES, FeatureTypeProperty.FETCH_MODE)) {
+ addHeaderComponent(ButtonHelper.createIconButton(Captions.externalMessageFetch, VaadinIcons.REFRESH, e -> {
+ checkForConcurrentEventsAndFetch();
+ }, ValoTheme.BUTTON_PRIMARY));
+ }
if (isBulkEditAllowed()) {
btnEnterBulkEditMode = ButtonHelper.createIconButton(Captions.actionEnterBulkEditMode, VaadinIcons.CHECK_SQUARE_O, e -> {
@@ -162,8 +168,10 @@ public HorizontalLayout createStatusFilterBar() {
createAndAddStatusButton(ExternalMessageStatus.UNPROCESSED, statusFilterLayout);
createAndAddStatusButton(ExternalMessageStatus.PROCESSED, statusFilterLayout);
- createAndAddStatusButton(ExternalMessageStatus.UNCLEAR, statusFilterLayout);
- createAndAddStatusButton(ExternalMessageStatus.FORWARDED, statusFilterLayout);
+ if (!FacadeProvider.getConfigFacade().isConfiguredCountry(CountryHelper.COUNTRY_CODE_LUXEMBOURG)) {
+ createAndAddStatusButton(ExternalMessageStatus.UNCLEAR, statusFilterLayout);
+ createAndAddStatusButton(ExternalMessageStatus.FORWARDED, statusFilterLayout);
+ }
HorizontalLayout actionButtonsLayout = new HorizontalLayout();
actionButtonsLayout.setSpacing(true);
@@ -230,7 +238,14 @@ private void updateStatusButtons() {
activeStatus = (ExternalMessageStatus) activeStatusButton.getData();
}
- grid.updateProcessColumnVisibility(activeStatus == null || activeStatus.isProcessable());
+ boolean processingPossible = (FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.CASE_SURVEILANCE)
+ && Objects.requireNonNull(UserProvider.getCurrent()).hasAllUserRights(UserRight.CASE_CREATE, UserRight.CASE_EDIT))
+ || (FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.CONTACT_TRACING)
+ && Objects.requireNonNull(UserProvider.getCurrent()).hasAllUserRights(UserRight.CONTACT_CREATE, UserRight.CONTACT_EDIT))
+ || (FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.EVENT_SURVEILLANCE)
+ && Objects.requireNonNull(UserProvider.getCurrent())
+ .hasAllUserRights(UserRight.EVENTPARTICIPANT_CREATE, UserRight.EVENTPARTICIPANT_EDIT));
+ grid.updateProcessColumnVisibility((activeStatus == null || activeStatus.isProcessable()) && processingPossible);
}
private Button createAndAddStatusButton(@Nullable ExternalMessageStatus status, HorizontalLayout buttonLayout) {
diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/labmessage/LabMessageProcessingFlow.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/labmessage/LabMessageProcessingFlow.java
index ad3feb8c804..0432d36aa56 100644
--- a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/labmessage/LabMessageProcessingFlow.java
+++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/labmessage/LabMessageProcessingFlow.java
@@ -53,6 +53,7 @@
import de.symeda.sormas.api.event.SimilarEventParticipantDto;
import de.symeda.sormas.api.externalmessage.ExternalMessageDto;
import de.symeda.sormas.api.externalmessage.labmessage.SampleReportDto;
+import de.symeda.sormas.api.feature.FeatureType;
import de.symeda.sormas.api.i18n.Captions;
import de.symeda.sormas.api.i18n.I18nProperties;
import de.symeda.sormas.api.i18n.Strings;
@@ -117,11 +118,23 @@ protected void handlePickOrCreateEntry(
EntrySelectionField.Options.Builder optionsBuilder = new EntrySelectionField.Options.Builder().addSelectCase(similarCases)
.addSelectContact(similarContacts)
.addSelectEventParticipant(similarEventParticipants)
- .addCreateEntry(EntrySelectionField.OptionType.CREATE_CASE)
- .addCreateEntry(EntrySelectionField.OptionType.CREATE_CONTACT)
- .addCreateEntry(EntrySelectionField.OptionType.CREATE_EVENT_PARTICIPANT);
-
- showPickOrCreateEntryWindow(optionsBuilder.build(), labMessage, callback);
+ .addCreateEntry(EntrySelectionField.OptionType.CREATE_CASE, FeatureType.CASE_SURVEILANCE, UserRight.CASE_CREATE, UserRight.CASE_EDIT)
+ .addCreateEntry(
+ EntrySelectionField.OptionType.CREATE_CONTACT,
+ FeatureType.CONTACT_TRACING,
+ UserRight.CONTACT_CREATE,
+ UserRight.CONTACT_EDIT)
+ .addCreateEntry(
+ EntrySelectionField.OptionType.CREATE_EVENT_PARTICIPANT,
+ FeatureType.EVENT_SURVEILLANCE,
+ UserRight.EVENTPARTICIPANT_CREATE,
+ UserRight.EVENTPARTICIPANT_EDIT);
+
+ if (optionsBuilder.size() > 1) {
+ showPickOrCreateEntryWindow(optionsBuilder.build(), labMessage, callback);
+ } else {
+ callback.done(optionsBuilder.getSingleAvailableCreateResult());
+ }
}
@Override
diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/labmessage/processing/AbstractLabMessageProcessingFlow.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/labmessage/processing/AbstractLabMessageProcessingFlow.java
index 6dd2e2244fa..d826afd79dd 100644
--- a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/labmessage/processing/AbstractLabMessageProcessingFlow.java
+++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/labmessage/processing/AbstractLabMessageProcessingFlow.java
@@ -15,7 +15,9 @@
package de.symeda.sormas.ui.externalmessage.labmessage.processing;
+import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.function.Consumer;
@@ -38,6 +40,7 @@
import de.symeda.sormas.api.event.SimilarEventParticipantDto;
import de.symeda.sormas.api.externalmessage.ExternalMessageDto;
import de.symeda.sormas.api.externalmessage.labmessage.SampleReportDto;
+import de.symeda.sormas.api.feature.FeatureType;
import de.symeda.sormas.api.infrastructure.country.CountryReferenceDto;
import de.symeda.sormas.api.person.PersonDto;
import de.symeda.sormas.api.person.PersonReferenceDto;
@@ -46,6 +49,8 @@
import de.symeda.sormas.api.sample.SampleDto;
import de.symeda.sormas.api.sample.SampleSimilarityCriteria;
import de.symeda.sormas.api.user.UserDto;
+import de.symeda.sormas.api.user.UserRight;
+import de.symeda.sormas.ui.UserProvider;
import de.symeda.sormas.ui.externalmessage.ExternalMessageMapper;
import de.symeda.sormas.ui.externalmessage.processing.AbstractProcessingFlow;
import de.symeda.sormas.ui.externalmessage.processing.PersonAndPickOrCreateEntryResult;
@@ -355,6 +360,10 @@ protected abstract void handlePickOrCreateEntry(
private List getSimilarContacts(PersonReferenceDto selectedPerson, ExternalMessageDto externalMessage) {
+ if (FacadeProvider.getFeatureConfigurationFacade().isFeatureDisabled(FeatureType.CONTACT_TRACING)
+ || !Objects.requireNonNull(UserProvider.getCurrent()).hasAllUserRights(UserRight.CONTACT_CREATE, UserRight.CONTACT_EDIT)) {
+ return Collections.emptyList();
+ }
ContactSimilarityCriteria contactSimilarityCriteria = new ContactSimilarityCriteria();
contactSimilarityCriteria.setPerson(selectedPerson);
contactSimilarityCriteria.setDisease(externalMessage.getDisease());
@@ -364,6 +373,12 @@ private List getSimilarContacts(PersonReferenceDto selectedPe
private List getSimilarEventParticipants(PersonReferenceDto selectedPerson, ExternalMessageDto labMessage) {
+ if (FacadeProvider.getFeatureConfigurationFacade().isFeatureDisabled(FeatureType.EVENT_SURVEILLANCE)
+ || !Objects.requireNonNull(UserProvider.getCurrent())
+ .hasAllUserRights(UserRight.EVENTPARTICIPANT_CREATE, UserRight.EVENTPARTICIPANT_EDIT)) {
+ return Collections.emptyList();
+ }
+
EventParticipantCriteria eventParticipantCriteria = new EventParticipantCriteria();
eventParticipantCriteria.setPerson(selectedPerson);
eventParticipantCriteria.setDisease(labMessage.getDisease());
diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/processing/AbstractProcessingFlow.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/processing/AbstractProcessingFlow.java
index 07329d8465d..1c8360dfc64 100644
--- a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/processing/AbstractProcessingFlow.java
+++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/processing/AbstractProcessingFlow.java
@@ -15,7 +15,9 @@
package de.symeda.sormas.ui.externalmessage.processing;
+import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
@@ -25,9 +27,12 @@
import de.symeda.sormas.api.caze.CaseSelectionDto;
import de.symeda.sormas.api.caze.CaseSimilarityCriteria;
import de.symeda.sormas.api.externalmessage.ExternalMessageDto;
+import de.symeda.sormas.api.feature.FeatureType;
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.UserRight;
+import de.symeda.sormas.ui.UserProvider;
import de.symeda.sormas.ui.externalmessage.ExternalMessageMapper;
import de.symeda.sormas.ui.externalmessage.labmessage.processing.AbstractLabMessageProcessingFlow;
import de.symeda.sormas.ui.externalmessage.processing.flow.FlowThen;
@@ -99,6 +104,11 @@ private PersonDto buildPerson(ExternalMessageMapper mapper) {
protected List getSimilarCases(PersonReferenceDto selectedPerson, ExternalMessageDto externalMessageDto) {
+ if (FacadeProvider.getFeatureConfigurationFacade().isFeatureDisabled(FeatureType.CASE_SURVEILANCE)
+ || !Objects.requireNonNull(UserProvider.getCurrent()).hasAllUserRights(UserRight.CASE_CREATE, UserRight.CASE_EDIT)) {
+ return Collections.emptyList();
+ }
+
CaseCriteria caseCriteria = new CaseCriteria();
caseCriteria.person(selectedPerson);
caseCriteria.disease(externalMessageDto.getDisease());
diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/processing/EntrySelectionField.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/processing/EntrySelectionField.java
index f12be051946..4ba235c918b 100644
--- a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/processing/EntrySelectionField.java
+++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/processing/EntrySelectionField.java
@@ -34,14 +34,18 @@
import com.vaadin.ui.RadioButtonGroup;
import com.vaadin.ui.VerticalLayout;
+import de.symeda.sormas.api.FacadeProvider;
import de.symeda.sormas.api.caze.CaseSelectionDto;
import de.symeda.sormas.api.contact.SimilarContactDto;
import de.symeda.sormas.api.event.SimilarEventParticipantDto;
import de.symeda.sormas.api.externalmessage.ExternalMessageDto;
import de.symeda.sormas.api.externalmessage.labmessage.SampleReportDto;
+import de.symeda.sormas.api.feature.FeatureType;
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.user.UserRight;
+import de.symeda.sormas.ui.UserProvider;
import de.symeda.sormas.ui.caze.components.caseselection.CaseSelectionGrid;
import de.symeda.sormas.ui.contact.ContactSelectionGrid;
import de.symeda.sormas.ui.events.EventParticipantSelectionGrid;
@@ -405,21 +409,49 @@ public Builder() {
}
public Builder addSelectCase(List selectableCases) {
- return add(OptionType.SELECT_CASE, selectableCases);
+ if (!selectableCases.isEmpty()
+ && FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.CASE_SURVEILANCE)
+ && Objects.requireNonNull(UserProvider.getCurrent()).hasAllUserRights(UserRight.CASE_CREATE, UserRight.CASE_EDIT)) {
+ return add(OptionType.SELECT_CASE, selectableCases);
+ } else {
+ return this;
+ }
}
public Builder addSelectContact(List selectableContacts) {
- return add(OptionType.SELECT_CONTACT, selectableContacts);
+ if (!selectableContacts.isEmpty()
+ && FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.CONTACT_TRACING)
+ && Objects.requireNonNull(UserProvider.getCurrent()).hasAllUserRights(UserRight.CONTACT_CREATE, UserRight.CONTACT_EDIT)) {
+ return add(OptionType.SELECT_CONTACT, selectableContacts);
+ } else {
+ return this;
+ }
}
public Builder addSelectEventParticipant(List selectableEventParticipants) {
- return add(OptionType.SELECT_EVENT_PARTICIPANT, selectableEventParticipants);
+ if (!selectableEventParticipants.isEmpty()
+ && FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.EVENT_SURVEILLANCE)
+ && Objects.requireNonNull(UserProvider.getCurrent())
+ .hasAllUserRights(UserRight.EVENTPARTICIPANT_CREATE, UserRight.EVENTPARTICIPANT_EDIT)) {
+ return add(OptionType.SELECT_EVENT_PARTICIPANT, selectableEventParticipants);
+ } else {
+ return this;
+ }
}
public Builder addCreateEntry(OptionType optionType) {
return add(optionType, null);
}
+ public Builder addCreateEntry(OptionType optionType, FeatureType requiredFeatureType, UserRight... requiredUserRights) {
+ if (FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(requiredFeatureType)
+ && Objects.requireNonNull(UserProvider.getCurrent()).hasAllUserRights(requiredUserRights)) {
+ return addCreateEntry(optionType);
+ } else {
+ return this;
+ }
+ }
+
private Builder add(OptionType optionType, List extends Serializable> selectableOptions) {
options.add(new Option<>(optionType, selectableOptions));
@@ -429,6 +461,32 @@ private Builder add(OptionType optionType, List extends Serializable> selectab
public Options build() {
return new Options(options);
}
+
+ public int size() {
+ return options.size();
+ }
+
+ public PickOrCreateEntryResult getSingleAvailableCreateResult() {
+ if (size() != 1) {
+ return null;
+ } else {
+ PickOrCreateEntryResult result = new PickOrCreateEntryResult();
+ switch (options.get(0).type) {
+ case CREATE_CASE:
+ result.setNewCase(true);
+ break;
+ case CREATE_CONTACT:
+ result.setNewContact(true);
+ break;
+ case CREATE_EVENT_PARTICIPANT:
+ result.setNewEventParticipant(true);
+ break;
+ default:
+ throw new IllegalArgumentException(options.get(0).type.toString());
+ }
+ return result;
+ }
+ }
}
}
}
diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/processing/ExternalMessageProcessingUIHelper.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/processing/ExternalMessageProcessingUIHelper.java
index cf1186bdd85..71c55872482 100644
--- a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/processing/ExternalMessageProcessingUIHelper.java
+++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/processing/ExternalMessageProcessingUIHelper.java
@@ -135,6 +135,7 @@ public static void showPickOrCreateEntryWindow(
EntrySelectionField.Options options,
ExternalMessageDto labMessage,
AbstractProcessingFlow.HandlerCallback callback) {
+
EntrySelectionField selectField = new EntrySelectionField(labMessage, options);
final CommitDiscardWrapperComponent selectionField = new CommitDiscardWrapperComponent<>(selectField);
diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/importer/DataImporter.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/importer/DataImporter.java
index bb30eefe9e6..e09bf85a841 100644
--- a/sormas-ui/src/main/java/de/symeda/sormas/ui/importer/DataImporter.java
+++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/importer/DataImporter.java
@@ -259,6 +259,7 @@ public ImportResultStatus runImport() throws IOException, InvalidColumnException
String[] entityClasses;
if (hasEntityClassRow) {
entityClasses = readNextValidLine(csvReader);
+ errorReportCsvWriter.writeNext(entityClasses);
} else {
entityClasses = null;
}
diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/environmentsample/EnvironmentSampleController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/environmentsample/EnvironmentSampleController.java
index e6f88dfa217..c183ea7dfff 100644
--- a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/environmentsample/EnvironmentSampleController.java
+++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/environmentsample/EnvironmentSampleController.java
@@ -178,6 +178,6 @@ public void create(EnvironmentDto environment, Runnable callback) {
}
});
- VaadinUiUtil.showModalPopupWindow(editView, I18nProperties.getString(Strings.headingCreateNewTask));
+ VaadinUiUtil.showModalPopupWindow(editView, I18nProperties.getString(Strings.headingCreateNewEnvironmentSample));
}
}
diff --git a/sormas-ui/src/main/resources/SORMAS_Environment_Import_Guide.docx b/sormas-ui/src/main/resources/SORMAS_Environment_Import_Guide.docx
index 5f49642d4a9..7d4b8a5196a 100644
Binary files a/sormas-ui/src/main/resources/SORMAS_Environment_Import_Guide.docx and b/sormas-ui/src/main/resources/SORMAS_Environment_Import_Guide.docx differ
diff --git a/sormas-ui/src/main/resources/SORMAS_Environment_Import_Guide.pdf b/sormas-ui/src/main/resources/SORMAS_Environment_Import_Guide.pdf
index be47a4685d4..5d3f6dd511f 100644
Binary files a/sormas-ui/src/main/resources/SORMAS_Environment_Import_Guide.pdf and b/sormas-ui/src/main/resources/SORMAS_Environment_Import_Guide.pdf differ
diff --git a/sormas-ui/src/test/java/de/symeda/sormas/ui/caze/importer/CaseImporterTest.java b/sormas-ui/src/test/java/de/symeda/sormas/ui/caze/importer/CaseImporterTest.java
index ed72d713ff0..755c3bf2135 100644
--- a/sormas-ui/src/test/java/de/symeda/sormas/ui/caze/importer/CaseImporterTest.java
+++ b/sormas-ui/src/test/java/de/symeda/sormas/ui/caze/importer/CaseImporterTest.java
@@ -276,8 +276,8 @@ protected void handleCaseSimilarity(CaseImportSimilarityInput input, Consumer errorRows = CSVUtils.createBomCsvReader(errorStream).readAll();
- if (errorRows.size() > 1) {
- assertThat("Error during import: " + StringUtils.join(errorRows.get(1), ", "), errorRows, hasSize(0));
+ if (errorRows.size() > 2) {
+ assertThat("Error during import: " + StringUtils.join(errorRows.get(2), ", "), errorRows, hasSize(0));
}
assertEquals(ImportResultStatus.COMPLETED, importResult);
diff --git a/sormas-ui/src/test/java/de/symeda/sormas/ui/contact/importer/ContactImporterTest.java b/sormas-ui/src/test/java/de/symeda/sormas/ui/contact/importer/ContactImporterTest.java
index 50cb6c5e76e..7bc93bdb37a 100644
--- a/sormas-ui/src/test/java/de/symeda/sormas/ui/contact/importer/ContactImporterTest.java
+++ b/sormas-ui/src/test/java/de/symeda/sormas/ui/contact/importer/ContactImporterTest.java
@@ -223,8 +223,8 @@ public void testImportContacts() throws IOException, InvalidColumnException, Int
InputStream errorStream =
new ByteArrayInputStream(((ContactImporterExtension) contactImporter).stringBuilder.toString().getBytes(StandardCharsets.UTF_8));
List errorRows = CSVUtils.createBomCsvReader(errorStream).readAll();
- if (errorRows.size() > 1) {
- assertThat("Error during import: " + StringUtils.join(errorRows.get(1), ", "), errorRows, hasSize(0));
+ if (errorRows.size() > 2) {
+ assertThat("Error during import: " + StringUtils.join(errorRows.get(2), ", "), errorRows, hasSize(0));
}
assertEquals(ImportResultStatus.COMPLETED, importResult);
diff --git a/sormas-ui/src/test/java/de/symeda/sormas/ui/importexport/ImportExportTest.java b/sormas-ui/src/test/java/de/symeda/sormas/ui/importexport/ImportExportTest.java
index 26968294daa..8d02ac881e0 100644
--- a/sormas-ui/src/test/java/de/symeda/sormas/ui/importexport/ImportExportTest.java
+++ b/sormas-ui/src/test/java/de/symeda/sormas/ui/importexport/ImportExportTest.java
@@ -169,8 +169,8 @@ else if (String.join(".", CaseDataDto.PERSON, PersonDto.FIRST_NAME).equals(colum
InputStream errorStream = new ByteArrayInputStream(caseImporter.stringBuilder.toString().getBytes(StandardCharsets.UTF_8));
List errorRows = CSVUtils.createBomCsvReader(errorStream).readAll();
- if (errorRows.size() > 1) {
- assertThat("Error during import: " + StringUtils.join(errorRows.get(1), ", "), errorRows, hasSize(0));
+ if (errorRows.size() > 2) {
+ assertThat("Error during import: " + StringUtils.join(errorRows.get(2), ", "), errorRows, hasSize(0));
}
PersonCriteria importPersonCriteria = new PersonCriteria();
@@ -324,8 +324,8 @@ else if (String.join(".", ContactDto.PERSON, PersonDto.FIRST_NAME).equals(column
InputStream errorStream = new ByteArrayInputStream(contactImporter.stringBuilder.toString().getBytes(StandardCharsets.UTF_8));
List errorRows = CSVUtils.createBomCsvReader(errorStream).readAll();
- if (errorRows.size() > 1) {
- assertThat("Error during import: " + StringUtils.join(errorRows.get(1), ", "), errorRows, hasSize(0));
+ if (errorRows.size() > 2) {
+ assertThat("Error during import: " + StringUtils.join(errorRows.get(2), ", "), errorRows, hasSize(0));
}
PersonCriteria importPersonCriteria = new PersonCriteria();
diff --git a/sormas-widgetset/pom.xml b/sormas-widgetset/pom.xml
index 88bc5a439c9..47a46de2fd2 100644
--- a/sormas-widgetset/pom.xml
+++ b/sormas-widgetset/pom.xml
@@ -3,7 +3,7 @@
sormas-base
de.symeda.sormas
- 1.89.0-SNAPSHOT
+ 1.90.0-SNAPSHOT
../sormas-base
4.0.0