From a64e81cf1d5caae142b0cd9bd01da112acda8e13 Mon Sep 17 00:00:00 2001 From: Bal Andrei Date: Wed, 9 Nov 2022 17:48:58 +0200 Subject: [PATCH 001/166] #7305 Restrict mobile app synchronization - added a max change date feature type property with default value to X=30 - in case the feature configuration for limited synchronization is enabled, than entities that are last updated before currentDate - X will not be synced with mobile app - all entities that are not updated before currentDate - X will be deleted from mobile app DB --- .../sormas/api/feature/FeatureType.java | 3 +- .../api/feature/FeatureTypeProperty.java | 1 + .../sormas/backend/caze/CaseService.java | 35 +++++++++++++++-- .../clinicalcourse/ClinicalVisitService.java | 37 ++++++++++++++++++ .../common/AdoServiceWithUserFilter.java | 31 +++++++++++++++ .../backend/contact/ContactService.java | 35 +++++++++++++++-- .../event/EventParticipantService.java | 35 +++++++++++++++++ .../sormas/backend/event/EventService.java | 35 +++++++++++++++++ .../immunization/ImmunizationService.java | 26 +++++++++++++ .../sormas/backend/person/PersonService.java | 29 ++++++++++++++ .../report/AggregateReportService.java | 31 +++++++++++++++ .../backend/report/WeeklyReportService.java | 30 +++++++++++++++ .../backend/sample/AdditionalTestService.java | 38 +++++++++++++++++++ .../backend/sample/PathogenTestService.java | 36 ++++++++++++++++++ .../sormas/backend/sample/SampleService.java | 30 +++++++++++++++ .../sormas/backend/task/TaskService.java | 36 ++++++++++++++++-- .../backend/therapy/PrescriptionService.java | 38 +++++++++++++++++++ .../backend/therapy/TreatmentService.java | 38 +++++++++++++++++++ .../sormas/backend/visit/VisitService.java | 35 ++++++++++++++++- .../caze/CaseFacadeEjbUserFilterTest.java | 2 +- .../common/AdoServiceWithUserFilterTest.java | 2 +- 21 files changed, 569 insertions(+), 14 deletions(-) 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 b08287e6a9c..d0ae97c6800 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 @@ -72,7 +72,8 @@ public enum FeatureType { TRAVEL_ENTRIES(true, false, null, null, null), DASHBOARD(true, true, null, null, null), - LIMITED_SYNCHRONIZATION(true, false, null, null, ImmutableMap.of(FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES, Boolean.FALSE)), + EXCLUDE_NO_CASE_CLASSIFIED(true, false, null, null, ImmutableMap.of(FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES, Boolean.FALSE)), + LIMITED_SYNCHRONIZATION(true, false, null, null, ImmutableMap.of(FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, 30)), // FEATURE EXTENSIONS ASSIGN_TASKS_TO_HIGHER_LEVEL(true, 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 896845fd63e..612abb42708 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 @@ -23,6 +23,7 @@ public enum FeatureTypeProperty { ALLOW_FREE_EDITING(Boolean.class), THRESHOLD_IN_DAYS(Integer.class), EXCLUDE_NO_CASE_CLASSIFIED_CASES(Boolean.class), + MAX_CHANGEDATE_SYNCHRONIZATION(Integer.class), S2S_SHARING(Boolean.class), SHARE_ASSOCIATED_CONTACTS(Boolean.class), SHARE_SAMPLES(Boolean.class), 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 58f82c28ee4..63515735900 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 @@ -257,6 +257,28 @@ public List findBy(CaseCriteria caseCriteria, boolean ignoreUserFilter) { return em.createQuery(cq).getResultList(); } + @Override + protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Case.CHANGE_DATE), timestamp)); + } + return null; + } + + @Override + protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Case.CHANGE_DATE), timestamp)); + } + return null; + } + @Override @SuppressWarnings("rawtypes") protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { @@ -296,6 +318,13 @@ public List getAllActiveUuids() { filter = CriteriaBuilderHelper.and(cb, filter, userFilter); } + if (RequestContextHolder.isMobileSync()) { + Predicate predicate = limitSynchronizationFilter(cb, from); + if (predicate != null) { + filter = CriteriaBuilderHelper.and(cb, predicate); + } + } + cq.where(filter); cq.select(from.get(Case.UUID)); @@ -557,9 +586,9 @@ public List getDeletedUuidsSince(Date since) { @Override protected List getAdditionalObsoleteUuidsPredicates(Date since, CriteriaBuilder cb, CriteriaQuery cq, Root from) { - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.EXCLUDE_NO_CASE_CLASSIFIED) && featureConfigurationFacade - .isPropertyValueTrue(FeatureType.LIMITED_SYNCHRONIZATION, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES)) { + .isPropertyValueTrue(FeatureType.EXCLUDE_NO_CASE_CLASSIFIED, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES)) { return Collections.singletonList(createObsoleteLimitedSyncCasePredicate(cb, from, since, getCurrentUser())); } else { return Collections.emptyList(); @@ -1425,7 +1454,7 @@ public Predicate createUserFilter(CaseQueryContext caseQueryContext, CaseUserFil if ((userFilterCriteria == null || !userFilterCriteria.isExcludeLimitedSyncRestrictions()) && featureConfigurationFacade - .isPropertyValueTrue(FeatureType.LIMITED_SYNCHRONIZATION, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES) + .isPropertyValueTrue(FeatureType.EXCLUDE_NO_CASE_CLASSIFIED, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES) && RequestContextHolder.isMobileSync()) { final Predicate limitedCaseSyncPredicate = cb.not( cb.and( diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java index 2f66c3f4072..fcefcc56400 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java @@ -1,6 +1,7 @@ package de.symeda.sormas.backend.clinicalcourse; import java.sql.Timestamp; +import java.util.Date; import java.util.List; import javax.ejb.EJB; @@ -14,7 +15,11 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; +import de.symeda.sormas.api.RequestContextHolder; import de.symeda.sormas.api.clinicalcourse.ClinicalVisitCriteria; +import de.symeda.sormas.api.feature.FeatureType; +import de.symeda.sormas.api.feature.FeatureTypeProperty; +import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.caze.CaseJoins; import de.symeda.sormas.backend.caze.CaseQueryContext; @@ -23,6 +28,7 @@ import de.symeda.sormas.backend.common.ChangeDateFilterBuilder; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; import de.symeda.sormas.backend.common.JurisdictionCheckService; +import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import de.symeda.sormas.backend.symptoms.Symptoms; import de.symeda.sormas.backend.user.User; @@ -32,6 +38,8 @@ public class ClinicalVisitService extends AdoServiceWithUserFilter from) { from.fetch(ClinicalVisit.SYMPTOMS); } + @Override + protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(ClinicalVisit.CHANGE_DATE), timestamp)); + } + return null; + } + + @Override + protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(ClinicalVisit.CHANGE_DATE), timestamp)); + } + return null; + } + public List getAllActiveUuids(User user) { CriteriaBuilder cb = em.getCriteriaBuilder(); @@ -90,6 +120,13 @@ public List getAllActiveUuids(User user) { filter = CriteriaBuilderHelper.and(cb, filter, userFilter); } + if (RequestContextHolder.isMobileSync()) { + Predicate predicate = limitSynchronizationFilter(cb, from); + if (predicate != null) { + filter = CriteriaBuilderHelper.and(cb, predicate); + } + } + cq.where(filter); cq.select(from.get(ClinicalVisit.UUID)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilter.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilter.java index acad33d20ae..41bb4e8d9e1 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilter.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilter.java @@ -11,6 +11,7 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; +import de.symeda.sormas.api.RequestContextHolder; import org.apache.commons.lang3.StringUtils; import de.symeda.sormas.backend.user.User; @@ -29,6 +30,14 @@ public AdoServiceWithUserFilter(Class elementClass) { @SuppressWarnings("rawtypes") public abstract Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from); + protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { + return null; + } + + protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + /** * Default filter for {@link #getAllAfter(Date)} to data that is allowed for the user to access and relevant for sync. * If you override this method it should usually include {@link #createUserFilter(CriteriaBuilder, CriteriaQuery, From)} @@ -52,6 +61,11 @@ public List getAllAfter(Date since, Integer batchSize, String lastSynchroni filter = CriteriaBuilderHelper.and(cb, filter, createChangeDateFilter(cb, from, since, lastSynchronizedUuid)); } + Predicate predicate = limitSynchronizationFilter(cb, from); + if (predicate != null) { + filter = CriteriaBuilderHelper.and(cb, predicate); + } + return filter; }, batchSize); } @@ -63,6 +77,11 @@ public List getAllUuids() { Root from = cq.from(getElementClass()); Predicate filter = createUserFilter(cb, cq, from); + Predicate predicate = limitSynchronizationFilter(cb, from); + if (predicate != null) { + filter = CriteriaBuilderHelper.and(cb, predicate); + } + if (filter != null) { cq.where(filter); } @@ -79,6 +98,11 @@ public List getAllIds(User user) { if (user != null) { Predicate filter = createUserFilter(cb, cq, from); + Predicate predicate = limitSynchronizationFilter(cb, from); + if (predicate != null) { + filter = CriteriaBuilderHelper.and(cb, predicate); + } + if (filter != null) { cq.where(filter); } @@ -115,6 +139,13 @@ public List getObsoleteUuidsSince(Date since) { filter = CriteriaBuilderHelper.and(cb, filter, contentFilter); + if (RequestContextHolder.isMobileSync()) { + Predicate predicate = limitSynchronizationFilterObsoleteEntities(cb, from); + if (predicate != null) { + filter = CriteriaBuilderHelper.and(cb, predicate); + } + } + cq.where(filter); cq.select(from.get(AbstractDomainObject.UUID)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java index 8a1bca7128e..a5d66c780a3 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java @@ -201,6 +201,28 @@ public List findBy(ContactCriteria contactCriteria, User user) { return em.createQuery(cq).getResultList(); } + @Override + protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Contact.CHANGE_DATE), timestamp)); + } + return null; + } + + @Override + protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Contact.CHANGE_DATE), timestamp)); + } + return null; + } + @Override @SuppressWarnings("rawtypes") protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { @@ -268,6 +290,13 @@ public List getAllActiveUuids(User user) { filter = CriteriaBuilderHelper.and(cb, filter, userFilter); } + if (RequestContextHolder.isMobileSync()) { + Predicate predicate = limitSynchronizationFilter(cb, from); + if (predicate != null) { + filter = CriteriaBuilderHelper.and(cb, predicate); + } + } + cq.where(filter); cq.select(from.get(Contact.UUID)); @@ -486,9 +515,9 @@ public List getDeletedUuidsSince(User user, Date since) { @Override protected List getAdditionalObsoleteUuidsPredicates(Date since, CriteriaBuilder cb, CriteriaQuery cq, Root from) { - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.EXCLUDE_NO_CASE_CLASSIFIED) && featureConfigurationFacade - .isPropertyValueTrue(FeatureType.LIMITED_SYNCHRONIZATION, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES)) { + .isPropertyValueTrue(FeatureType.EXCLUDE_NO_CASE_CLASSIFIED, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES)) { ContactQueryContext contactQueryContext = new ContactQueryContext(cb, cq, from); return Collections.singletonList( @@ -1102,7 +1131,7 @@ public Predicate createUserFilterWithoutCase(ContactQueryContext qc, ContactCrit if ((contactCriteria == null || !contactCriteria.isExcludeLimitedSyncRestrictions()) && featureConfigurationFacade - .isPropertyValueTrue(FeatureType.LIMITED_SYNCHRONIZATION, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES) + .isPropertyValueTrue(FeatureType.EXCLUDE_NO_CASE_CLASSIFIED, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES) && RequestContextHolder.isMobileSync()) { final Predicate limitedCaseSyncPredicate = caseService.createLimitedSyncCasePredicate(cb, qc.getJoins().getCaze(), currentUser); filter = CriteriaBuilderHelper.and(cb, filter, limitedCaseSyncPredicate); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java index 26e6afb118f..50411340004 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java @@ -40,9 +40,12 @@ import de.symeda.sormas.api.Disease; import de.symeda.sormas.api.EditPermissionType; import de.symeda.sormas.api.EntityRelevanceStatus; +import de.symeda.sormas.api.RequestContextHolder; import de.symeda.sormas.api.caze.VaccinationStatus; import de.symeda.sormas.api.common.DeletionDetails; import de.symeda.sormas.api.event.EventParticipantCriteria; +import de.symeda.sormas.api.feature.FeatureType; +import de.symeda.sormas.api.feature.FeatureTypeProperty; import de.symeda.sormas.api.utils.DataHelper; import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.backend.common.AbstractCoreAdoService; @@ -51,6 +54,7 @@ import de.symeda.sormas.backend.common.ChangeDateFilterBuilder; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; import de.symeda.sormas.backend.contact.Contact; +import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import de.symeda.sormas.backend.person.Person; import de.symeda.sormas.backend.person.PersonQueryContext; import de.symeda.sormas.backend.sample.Sample; @@ -76,6 +80,8 @@ public class EventParticipantService extends AbstractCoreAdoService from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(EventParticipant.CHANGE_DATE), timestamp)); + } + return null; + } + + @Override + protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(EventParticipant.CHANGE_DATE), timestamp)); + } + return null; + } + public List getAllActiveUuids(User user) { CriteriaBuilder cb = em.getCriteriaBuilder(); @@ -119,6 +147,13 @@ public List getAllActiveUuids(User user) { filter = CriteriaBuilderHelper.and(cb, filter, userFilter); } + if (RequestContextHolder.isMobileSync()) { + Predicate predicate = limitSynchronizationFilter(cb, from); + if (predicate != null) { + filter = CriteriaBuilderHelper.and(cb, predicate); + } + } + cq.where(filter); cq.select(from.get(EventParticipant.UUID)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java index a2277a11431..20cd75825e4 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java @@ -40,6 +40,10 @@ import javax.persistence.criteria.Subquery; import javax.transaction.Transactional; +import de.symeda.sormas.api.RequestContextHolder; +import de.symeda.sormas.api.feature.FeatureType; +import de.symeda.sormas.api.feature.FeatureTypeProperty; +import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -131,6 +135,8 @@ public class EventService extends AbstractCoreAdoService { private EventFacadeEjb.EventFacadeEjbLocal eventFacade; @EJB private ExternalSurveillanceToolGatewayFacadeEjb.ExternalSurveillanceToolGatewayFacadeEjbLocal externalSurveillanceToolGatewayFacade; + @EJB + protected FeatureConfigurationFacadeEjb.FeatureConfigurationFacadeEjbLocal featureConfigurationFacade; public EventService() { super(Event.class); @@ -161,6 +167,28 @@ protected void fetchReferences(From from) { from.fetch(Event.EVENT_LOCATION); } + @Override + protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Event.CHANGE_DATE), timestamp)); + } + return null; + } + + @Override + protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Event.CHANGE_DATE), timestamp)); + } + return null; + } + public List getAllActiveUuids() { CriteriaBuilder cb = em.getCriteriaBuilder(); @@ -181,6 +209,13 @@ public List getAllActiveUuids() { filter = CriteriaBuilderHelper.and(cb, filter, userFilter); } + if (RequestContextHolder.isMobileSync()) { + Predicate predicate = limitSynchronizationFilter(cb, from); + if (predicate != null) { + filter = CriteriaBuilderHelper.and(cb, predicate); + } + } + cq.where(filter); cq.select(from.get(Event.UUID)); cq.distinct(true); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java index 454e71a2d08..d15bb1b4481 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java @@ -46,6 +46,7 @@ import de.symeda.sormas.api.immunization.ImmunizationStatus; import de.symeda.sormas.api.immunization.MeansOfImmunization; import de.symeda.sormas.api.user.UserRight; +import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.common.AbstractCoreAdoService; import de.symeda.sormas.backend.common.AbstractDomainObject; @@ -53,6 +54,7 @@ import de.symeda.sormas.backend.common.ChangeDateFilterBuilder; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; import de.symeda.sormas.backend.contact.Contact; +import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import de.symeda.sormas.backend.immunization.entity.DirectoryImmunization; import de.symeda.sormas.backend.immunization.entity.Immunization; import de.symeda.sormas.backend.immunization.transformers.ImmunizationListEntryDtoResultTransformer; @@ -84,6 +86,8 @@ public class ImmunizationService extends AbstractCoreAdoService { private SormasToSormasShareInfoFacadeEjbLocal sormasToSormasShareInfoFacade; @EJB private SormasToSormasShareInfoService sormasToSormasShareInfoService; + @EJB + protected FeatureConfigurationFacadeEjb.FeatureConfigurationFacadeEjbLocal featureConfigurationFacade; public ImmunizationService() { super(Immunization.class); @@ -114,6 +118,28 @@ public void deletePermanent(Immunization immunization) { super.deletePermanent(immunization); } + @Override + protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Immunization.CHANGE_DATE), timestamp)); + } + return null; + } + + @Override + protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Immunization.CHANGE_DATE), timestamp)); + } + return null; + } + public List getEntriesList(Long personId, Disease disease, Integer first, Integer max) { final CriteriaBuilder cb = em.getCriteriaBuilder(); final CriteriaQuery cq = cb.createQuery(Object[].class); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java index 001bae7bf02..e252706acd3 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java @@ -193,6 +193,28 @@ private boolean isPermitted(FeatureType featureType, UserRight userRight) { return getCurrentUser().hasUserRight(userRight) && featureConfigurationFacade.isFeatureEnabled(featureType); } + @Override + protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Person.CHANGE_DATE), timestamp)); + } + return null; + } + + @Override + protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Person.CHANGE_DATE), timestamp)); + } + return null; + } + @Override public List getAllUuids() { @@ -568,6 +590,13 @@ private List getAllAfter( } filter = and(cb, filter, dateFilter); } + + if (RequestContextHolder.isMobileSync()) { + Predicate predicate = limitSynchronizationFilter(cb, personJoin); + if (predicate != null) { + filter = CriteriaBuilderHelper.and(cb, predicate); + } + } if (filter != null) { cq.where(filter); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java index e821a9f3769..ff2a9c754ca 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java @@ -1,5 +1,7 @@ package de.symeda.sormas.backend.report; +import java.sql.Timestamp; +import java.util.Date; import java.util.List; import javax.ejb.EJB; @@ -13,10 +15,15 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; +import de.symeda.sormas.api.feature.FeatureType; +import de.symeda.sormas.api.feature.FeatureTypeProperty; import de.symeda.sormas.api.report.AggregateReportCriteria; import de.symeda.sormas.api.user.JurisdictionLevel; +import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.backend.common.AdoServiceWithUserFilter; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; +import de.symeda.sormas.backend.contact.Contact; +import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import de.symeda.sormas.backend.infrastructure.district.District; import de.symeda.sormas.backend.infrastructure.facility.Facility; import de.symeda.sormas.backend.infrastructure.pointofentry.PointOfEntry; @@ -31,6 +38,8 @@ public class AggregateReportService extends AdoServiceWithUserFilter from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(AggregateReport.CHANGE_DATE), timestamp)); + } + return null; + } + + @Override + protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(AggregateReport.CHANGE_DATE), timestamp)); + } + return null; + } + public List findBy(AggregateReportCriteria aggregateReportCriteria, User user) { CriteriaBuilder cb = em.getCriteriaBuilder(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java index 70d6e37164d..cf226055a4e 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java @@ -17,6 +17,8 @@ *******************************************************************************/ package de.symeda.sormas.backend.report; +import java.sql.Timestamp; +import java.util.Date; import java.util.List; import java.util.Optional; import java.util.stream.Stream; @@ -33,11 +35,15 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; +import de.symeda.sormas.api.feature.FeatureType; +import de.symeda.sormas.api.feature.FeatureTypeProperty; import de.symeda.sormas.api.report.WeeklyReportCriteria; import de.symeda.sormas.api.user.JurisdictionLevel; +import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.api.utils.EpiWeek; import de.symeda.sormas.backend.common.AdoServiceWithUserFilter; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; +import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import de.symeda.sormas.backend.infrastructure.district.DistrictService; import de.symeda.sormas.backend.infrastructure.facility.Facility; import de.symeda.sormas.backend.infrastructure.region.Region; @@ -57,6 +63,8 @@ public class WeeklyReportService extends AdoServiceWithUserFilter private DistrictService districtService; @EJB private UserService userService; + @EJB + protected FeatureConfigurationFacadeEjb.FeatureConfigurationFacadeEjbLocal featureConfigurationFacade; public WeeklyReportService() { super(WeeklyReport.class); @@ -113,6 +121,28 @@ public WeeklyReport getByEpiWeekAndUser(EpiWeek epiWeek, User user) { return QueryHelper.getSingleResult(em, cq); } + @Override + protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(WeeklyReport.CHANGE_DATE), timestamp)); + } + return null; + } + + @Override + protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(WeeklyReport.CHANGE_DATE), timestamp)); + } + return null; + } + /** * @see /sormas-backend/doc/UserDataAccess.md */ diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java index b06385f017a..6f0493740d7 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java @@ -1,6 +1,8 @@ package de.symeda.sormas.backend.sample; +import java.sql.Timestamp; import java.util.ArrayList; +import java.util.Date; import java.util.List; import javax.ejb.EJB; @@ -19,7 +21,11 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; +import de.symeda.sormas.api.RequestContextHolder; +import de.symeda.sormas.api.feature.FeatureType; +import de.symeda.sormas.api.feature.FeatureTypeProperty; import de.symeda.sormas.api.sample.AdditionalTestCriteria; +import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.api.utils.SortProperty; import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.common.AdoServiceWithUserFilter; @@ -28,6 +34,7 @@ import de.symeda.sormas.backend.common.JurisdictionCheckService; import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.event.EventParticipant; +import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import de.symeda.sormas.backend.user.User; import de.symeda.sormas.backend.util.QueryHelper; @@ -37,6 +44,8 @@ public class AdditionalTestService extends AdoServiceWithUserFilter from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(AdditionalTest.CHANGE_DATE), timestamp)); + } + return null; + } + + @Override + protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(AdditionalTest.CHANGE_DATE), timestamp)); + } + return null; + } + public Predicate buildCriteriaFilter(AdditionalTestCriteria additionalTestCriteria, CriteriaBuilder cb, Root from) { Predicate filter = createActiveSamplesFilter(cb, from); @@ -141,6 +172,13 @@ public List getAllActiveUuids(User user) { filter = CriteriaBuilderHelper.and(cb, filter, userFilter); } + if (RequestContextHolder.isMobileSync()) { + Predicate predicate = limitSynchronizationFilter(cb, from); + if (predicate != null) { + filter = CriteriaBuilderHelper.and(cb, predicate); + } + } + cq.where(filter); cq.select(from.get(AdditionalTest.UUID)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java index 5bf801d812c..9497fcc57fe 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java @@ -40,9 +40,13 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; +import de.symeda.sormas.api.RequestContextHolder; import de.symeda.sormas.api.common.DeletionDetails; +import de.symeda.sormas.api.feature.FeatureType; +import de.symeda.sormas.api.feature.FeatureTypeProperty; import de.symeda.sormas.api.sample.PathogenTestCriteria; import de.symeda.sormas.api.sample.PathogenTestResultType; +import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.api.utils.SortProperty; import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.common.AbstractDeletableAdoService; @@ -52,6 +56,7 @@ import de.symeda.sormas.backend.common.JurisdictionCheckService; import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.event.EventParticipant; +import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import de.symeda.sormas.backend.user.User; import de.symeda.sormas.backend.util.QueryHelper; @@ -61,6 +66,8 @@ public class PathogenTestService extends AbstractDeletableAdoService from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(PathogenTest.CHANGE_DATE), timestamp)); + } + return null; + } + + @Override + protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(PathogenTest.CHANGE_DATE), timestamp)); + } + return null; + } + public List getAllActiveUuids(User user) { CriteriaBuilder cb = em.getCriteriaBuilder(); @@ -92,6 +121,13 @@ public List getAllActiveUuids(User user) { filter = CriteriaBuilderHelper.and(cb, filter, userFilter); } + if (RequestContextHolder.isMobileSync()) { + Predicate predicate = limitSynchronizationFilter(cb, from); + if (predicate != null) { + filter = CriteriaBuilderHelper.and(cb, predicate); + } + } + cq.where(filter); cq.select(from.get(PathogenTest.UUID)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java index bcfe53b7c74..a34f11672d6 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java @@ -52,6 +52,7 @@ import javax.persistence.criteria.Selection; import javax.persistence.criteria.Subquery; +import de.symeda.sormas.api.feature.FeatureTypeProperty; import org.apache.commons.collections.CollectionUtils; import de.symeda.sormas.api.EntityRelevanceStatus; @@ -389,6 +390,28 @@ public List getIndexList(SampleCriteria sampleCriteria, Integer return samples; } + @Override + protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Sample.CHANGE_DATE), timestamp)); + } + return null; + } + + @Override + protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Sample.CHANGE_DATE), timestamp)); + } + return null; + } + public List getEntriesList(SampleCriteria sampleCriteria, Integer first, Integer max) { if (sampleCriteria == null) { return Collections.emptyList(); @@ -476,6 +499,13 @@ public List getAllActiveUuids(User user) { filter = CriteriaBuilderHelper.and(cb, filter, userFilter); } + if (RequestContextHolder.isMobileSync()) { + Predicate predicate = limitSynchronizationFilter(cb, from); + if (predicate != null) { + filter = CriteriaBuilderHelper.and(cb, predicate); + } + } + cq.where(filter); cq.select(from.get(Sample.UUID)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java index 6b854887499..ff74f1bace1 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java @@ -42,6 +42,7 @@ import javax.persistence.criteria.Root; import javax.persistence.criteria.Selection; +import de.symeda.sormas.api.utils.DateHelper; import org.apache.commons.lang3.ArrayUtils; import de.symeda.sormas.api.EntityRelevanceStatus; @@ -121,6 +122,28 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c return filter; } + @Override + protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Task.CHANGE_DATE), timestamp)); + } + return null; + } + + @Override + protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Task.CHANGE_DATE), timestamp)); + } + return null; + } + public List getAllActiveUuids(User user) { final CriteriaBuilder cb = em.getCriteriaBuilder(); @@ -135,6 +158,13 @@ public List getAllActiveUuids(User user) { filter = CriteriaBuilderHelper.and(cb, filter, userFilter); } + if (RequestContextHolder.isMobileSync()) { + Predicate predicate = limitSynchronizationFilter(cb, from); + if (predicate != null) { + filter = CriteriaBuilderHelper.and(cb, predicate); + } + } + cq.where(filter); cq.select(from.get(Task.UUID)); @@ -246,7 +276,7 @@ public Predicate createUserFilter(TaskQueryContext taskQueryContext, TaskCriteri if ((taskCriteria == null || !taskCriteria.isExcludeLimitedSyncRestrictions()) && featureConfigurationFacade - .isPropertyValueTrue(FeatureType.LIMITED_SYNCHRONIZATION, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES) + .isPropertyValueTrue(FeatureType.EXCLUDE_NO_CASE_CLASSIFIED, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES) && RequestContextHolder.isMobileSync()) { Predicate limitedCaseSyncPredicate = CriteriaBuilderHelper.and( @@ -263,9 +293,9 @@ public Predicate createUserFilter(TaskQueryContext taskQueryContext, TaskCriteri @Override protected List getAdditionalObsoleteUuidsPredicates(Date since, CriteriaBuilder cb, CriteriaQuery cq, Root from) { - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.EXCLUDE_NO_CASE_CLASSIFIED) && featureConfigurationFacade - .isPropertyValueTrue(FeatureType.LIMITED_SYNCHRONIZATION, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES)) { + .isPropertyValueTrue(FeatureType.EXCLUDE_NO_CASE_CLASSIFIED, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES)) { List predicates = new ArrayList<>(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java index c305da6e323..35c02a9af18 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java @@ -1,5 +1,7 @@ package de.symeda.sormas.backend.therapy; +import java.sql.Timestamp; +import java.util.Date; import java.util.List; import javax.ejb.EJB; @@ -13,6 +15,11 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; +import de.symeda.sormas.api.RequestContextHolder; +import de.symeda.sormas.api.feature.FeatureType; +import de.symeda.sormas.api.feature.FeatureTypeProperty; +import de.symeda.sormas.api.utils.DateHelper; +import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import org.apache.commons.lang3.StringUtils; import de.symeda.sormas.api.therapy.PrescriptionCriteria; @@ -32,6 +39,8 @@ public class PrescriptionService extends AdoServiceWithUserFilter @EJB private CaseService caseService; + @EJB + protected FeatureConfigurationFacadeEjb.FeatureConfigurationFacadeEjbLocal featureConfigurationFacade; public PrescriptionService() { super(Prescription.class); @@ -70,6 +79,28 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c return filter; } + @Override + protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Prescription.CHANGE_DATE), timestamp)); + } + return null; + } + + @Override + protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Prescription.CHANGE_DATE), timestamp)); + } + return null; + } + public List getAllActiveUuids(User user) { CriteriaBuilder cb = em.getCriteriaBuilder(); @@ -85,6 +116,13 @@ public List getAllActiveUuids(User user) { filter = CriteriaBuilderHelper.and(cb, filter, userFilter); } + if (RequestContextHolder.isMobileSync()) { + Predicate predicate = limitSynchronizationFilter(cb, from); + if (predicate != null) { + filter = CriteriaBuilderHelper.and(cb, predicate); + } + } + cq.where(filter); cq.select(from.get(Prescription.UUID)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java index 07065c409be..1e8238ab873 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java @@ -1,5 +1,7 @@ package de.symeda.sormas.backend.therapy; +import java.sql.Timestamp; +import java.util.Date; import java.util.List; import javax.ejb.EJB; @@ -14,6 +16,11 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; +import de.symeda.sormas.api.RequestContextHolder; +import de.symeda.sormas.api.feature.FeatureType; +import de.symeda.sormas.api.feature.FeatureTypeProperty; +import de.symeda.sormas.api.utils.DateHelper; +import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import org.apache.commons.lang3.StringUtils; import de.symeda.sormas.api.therapy.TreatmentCriteria; @@ -33,6 +40,8 @@ public class TreatmentService extends AdoServiceWithUserFilter implem @EJB private CaseService caseService; + @EJB + protected FeatureConfigurationFacadeEjb.FeatureConfigurationFacadeEjbLocal featureConfigurationFacade; public TreatmentService() { super(Treatment.class); @@ -70,6 +79,28 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c return filter; } + @Override + protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Treatment.CHANGE_DATE), timestamp)); + } + return null; + } + + @Override + protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Treatment.CHANGE_DATE), timestamp)); + } + return null; + } + public List getAllActiveUuids(User user) { CriteriaBuilder cb = em.getCriteriaBuilder(); @@ -85,6 +116,13 @@ public List getAllActiveUuids(User user) { filter = CriteriaBuilderHelper.and(cb, filter, userFilter); } + if (RequestContextHolder.isMobileSync()) { + Predicate predicate = limitSynchronizationFilter(cb, from); + if (predicate != null) { + filter = CriteriaBuilderHelper.and(cb, predicate); + } + } + cq.where(filter); cq.select(from.get(Treatment.UUID)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java index cce8a0d74b8..48ea63f5e61 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java @@ -40,8 +40,11 @@ import javax.persistence.criteria.Subquery; import de.symeda.sormas.api.Disease; +import de.symeda.sormas.api.RequestContextHolder; import de.symeda.sormas.api.caze.CaseLogic; import de.symeda.sormas.api.contact.ContactLogic; +import de.symeda.sormas.api.feature.FeatureType; +import de.symeda.sormas.api.feature.FeatureTypeProperty; import de.symeda.sormas.api.followup.FollowUpLogic; import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.api.visit.VisitCriteria; @@ -58,6 +61,7 @@ import de.symeda.sormas.backend.contact.ContactJoins; import de.symeda.sormas.backend.contact.ContactQueryContext; import de.symeda.sormas.backend.contact.ContactService; +import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import de.symeda.sormas.backend.person.Person; import de.symeda.sormas.backend.symptoms.Symptoms; import de.symeda.sormas.backend.user.User; @@ -73,6 +77,9 @@ public class VisitService extends BaseAdoService implements JurisdictionC @EJB private CaseService caseService; + @EJB + protected FeatureConfigurationFacadeEjb.FeatureConfigurationFacadeEjbLocal featureConfigurationFacade; + public VisitService() { super(Visit.class); } @@ -92,6 +99,26 @@ private Predicate inJurisdictionOrOwned(CriteriaBuilder cb, CriteriaQuery cq, Fr return inJurisdictionOrOwned(new VisitQueryContext(cb, cq, from)); } + protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Visit.CHANGE_DATE), timestamp)); + } + return null; + } + + protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (maxChangeDatePeriod != null) { + Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Visit.CHANGE_DATE), timestamp)); + } + return null; + } + public Predicate inJurisdictionOrOwned(VisitQueryContext queryContext) { CriteriaBuilder cb = queryContext.getCriteriaBuilder(); @@ -170,12 +197,16 @@ private List getAllActiveInCasesUuids() { public List getAllAfter(Date since, Integer batchSize, String lastSynchronizedUuid) { return getList((cb, cq, from) -> { - Predicate filter = createRelevantDataFilter(cb, cq, from); if (since != null) { filter = CriteriaBuilderHelper.and(cb, filter, createChangeDateFilter(cb, from, since, lastSynchronizedUuid)); } - + if (RequestContextHolder.isMobileSync()) { + Predicate predicate = limitSynchronizationFilter(cb, from); + if (predicate != null) { + filter = CriteriaBuilderHelper.and(cb, predicate); + } + } return filter; }, batchSize); } diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbUserFilterTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbUserFilterTest.java index 71bc7e39dc4..425f7bd3c31 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbUserFilterTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbUserFilterTest.java @@ -147,7 +147,7 @@ public void testGetCasesWithLimitedSynchronization() { FeatureConfigurationIndexDto featureConfiguration = new FeatureConfigurationIndexDto(DataHelper.createUuid(), null, null, null, null, null, true, null); - getFeatureConfigurationFacade().saveFeatureConfiguration(featureConfiguration, FeatureType.LIMITED_SYNCHRONIZATION); + getFeatureConfigurationFacade().saveFeatureConfiguration(featureConfiguration, FeatureType.EXCLUDE_NO_CASE_CLASSIFIED); SessionImpl em = (SessionImpl) getEntityManager(); QueryImplementor query = em.createQuery("select f from featureconfiguration f"); diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterTest.java index 196f57a5504..e0a48d7e709 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterTest.java @@ -34,7 +34,7 @@ public void testGetObsoleteUuidsSince() { FeatureConfigurationIndexDto featureConfiguration = new FeatureConfigurationIndexDto(DataHelper.createUuid(), null, null, null, null, null, true, null); - getFeatureConfigurationFacade().saveFeatureConfiguration(featureConfiguration, FeatureType.LIMITED_SYNCHRONIZATION); + getFeatureConfigurationFacade().saveFeatureConfiguration(featureConfiguration, FeatureType.EXCLUDE_NO_CASE_CLASSIFIED); SessionImpl em = (SessionImpl) getEntityManager(); QueryImplementor query = em.createQuery("select f from featureconfiguration f"); From d869c31a235441f633f669539c9cdda5350ff040 Mon Sep 17 00:00:00 2001 From: Bal Andrei Date: Fri, 11 Nov 2022 10:43:33 +0200 Subject: [PATCH 002/166] Merge conflicts & add a check if feature is enabled --- .../sormas/backend/caze/CaseService.java | 4 ++-- .../clinicalcourse/ClinicalVisitService.java | 5 +++-- ...doServiceWithUserFilterAndJurisdiction.java | 18 ++++++++++++------ .../sormas/backend/contact/ContactService.java | 4 ++-- .../backend/event/EventParticipantService.java | 4 ++-- .../sormas/backend/event/EventService.java | 4 ++-- .../immunization/ImmunizationService.java | 4 ++-- .../sormas/backend/person/PersonService.java | 4 ++-- .../backend/report/AggregateReportService.java | 8 +++++--- .../backend/report/WeeklyReportService.java | 4 ++-- .../backend/sample/AdditionalTestService.java | 4 ++-- .../backend/sample/PathogenTestService.java | 4 ++-- .../sormas/backend/sample/SampleService.java | 4 ++-- .../sormas/backend/task/TaskService.java | 4 ++-- .../backend/therapy/PrescriptionService.java | 4 ++-- .../backend/therapy/TreatmentService.java | 4 ++-- .../sormas/backend/visit/VisitService.java | 4 ++-- 17 files changed, 48 insertions(+), 39 deletions(-) diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseService.java index a7cf7cff4ce..5e1fcca1499 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 @@ -261,7 +261,7 @@ public List findBy(CaseCriteria caseCriteria, boolean ignoreUserFilter) { protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Case.CHANGE_DATE), timestamp)); } @@ -272,7 +272,7 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Case.CHANGE_DATE), timestamp)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java index ed055407b84..6b882c6e977 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java @@ -27,6 +27,7 @@ import de.symeda.sormas.backend.common.AdoServiceWithUserFilterAndJurisdiction; import de.symeda.sormas.backend.common.ChangeDateFilterBuilder; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; +import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import de.symeda.sormas.backend.symptoms.Symptoms; import de.symeda.sormas.backend.user.User; @@ -85,7 +86,7 @@ protected void fetchReferences(From from) { protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(ClinicalVisit.CHANGE_DATE), timestamp)); } @@ -96,7 +97,7 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(ClinicalVisit.CHANGE_DATE), timestamp)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java index 10b1281a1fa..fbec31912c6 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java @@ -67,9 +67,11 @@ public List getAllAfter(Date since, Integer batchSize, String lastSynchroni filter = CriteriaBuilderHelper.and(cb, filter, createChangeDateFilter(cb, from, since, lastSynchronizedUuid)); } - Predicate predicate = limitSynchronizationFilter(cb, from); - if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, predicate); + if (RequestContextHolder.isMobileSync()) { + Predicate predicate = limitSynchronizationFilter(cb, from); + if (predicate != null) { + filter = CriteriaBuilderHelper.and(cb, predicate); + } } return filter; @@ -104,9 +106,13 @@ public List getAllIds(User user) { if (user != null) { Predicate filter = createUserFilter(cb, cq, from); - Predicate predicate = limitSynchronizationFilter(cb, from); - if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, predicate); + + if (RequestContextHolder.isMobileSync()) + { + Predicate predicate = limitSynchronizationFilter(cb, from); + if (predicate != null) { + filter = CriteriaBuilderHelper.and(cb, predicate); + } } if (filter != null) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java index a028661e5eb..d8b5cdf8c99 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java @@ -205,7 +205,7 @@ public List findBy(ContactCriteria contactCriteria, User user) { protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Contact.CHANGE_DATE), timestamp)); } @@ -216,7 +216,7 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Contact.CHANGE_DATE), timestamp)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java index 49a07bec58c..0efab7c968c 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java @@ -111,7 +111,7 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(EventParticipant.CHANGE_DATE), timestamp)); } @@ -122,7 +122,7 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(EventParticipant.CHANGE_DATE), timestamp)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java index 64a9e2dd366..635f391dbd6 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java @@ -171,7 +171,7 @@ protected void fetchReferences(From from) { protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Event.CHANGE_DATE), timestamp)); } @@ -182,7 +182,7 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Event.CHANGE_DATE), timestamp)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java index 7398999cea7..564de16885b 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java @@ -122,7 +122,7 @@ public void deletePermanent(Immunization immunization) { protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Immunization.CHANGE_DATE), timestamp)); } @@ -133,7 +133,7 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Immunization.CHANGE_DATE), timestamp)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java index eede8196e8a..bc67c224b4e 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java @@ -196,7 +196,7 @@ private boolean isPermitted(FeatureType featureType, UserRight userRight) { protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Person.CHANGE_DATE), timestamp)); } @@ -207,7 +207,7 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Person.CHANGE_DATE), timestamp)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java index b75a2c99702..c6dd93efecb 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java @@ -1,5 +1,7 @@ package de.symeda.sormas.backend.report; +import java.sql.Timestamp; +import java.util.Date; import java.util.List; import javax.ejb.EJB; @@ -17,9 +19,9 @@ import de.symeda.sormas.api.feature.FeatureTypeProperty; import de.symeda.sormas.api.report.AggregateReportCriteria; import de.symeda.sormas.api.user.JurisdictionLevel; +import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.backend.common.AdoServiceWithUserFilterAndJurisdiction; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; -import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import de.symeda.sormas.backend.infrastructure.district.District; import de.symeda.sormas.backend.infrastructure.facility.Facility; @@ -189,7 +191,7 @@ public Predicate createUserFilter(AggregateReportQueryContext queryContext) { protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(AggregateReport.CHANGE_DATE), timestamp)); } @@ -200,7 +202,7 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(AggregateReport.CHANGE_DATE), timestamp)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java index 67fd07b5022..3f0657b767b 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java @@ -125,7 +125,7 @@ public WeeklyReport getByEpiWeekAndUser(EpiWeek epiWeek, User user) { protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(WeeklyReport.CHANGE_DATE), timestamp)); } @@ -136,7 +136,7 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(WeeklyReport.CHANGE_DATE), timestamp)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java index 14a8ba7bc63..def1166f833 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java @@ -67,7 +67,7 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(AdditionalTest.CHANGE_DATE), timestamp)); } @@ -78,7 +78,7 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(AdditionalTest.CHANGE_DATE), timestamp)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java index ab8521bcbf9..3a3f9cad82f 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java @@ -89,7 +89,7 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(PathogenTest.CHANGE_DATE), timestamp)); } @@ -100,7 +100,7 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(PathogenTest.CHANGE_DATE), timestamp)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java index a34f11672d6..28922613818 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java @@ -394,7 +394,7 @@ public List getIndexList(SampleCriteria sampleCriteria, Integer protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Sample.CHANGE_DATE), timestamp)); } @@ -405,7 +405,7 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Sample.CHANGE_DATE), timestamp)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java index 3b14f65850f..671c06a94f3 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java @@ -126,7 +126,7 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Task.CHANGE_DATE), timestamp)); } @@ -137,7 +137,7 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Task.CHANGE_DATE), timestamp)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java index 8ef3aaa9480..21b8421febc 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java @@ -82,7 +82,7 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Prescription.CHANGE_DATE), timestamp)); } @@ -93,7 +93,7 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Prescription.CHANGE_DATE), timestamp)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java index fcb75909ecc..c2bfcd0921b 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java @@ -82,7 +82,7 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Treatment.CHANGE_DATE), timestamp)); } @@ -93,7 +93,7 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Treatment.CHANGE_DATE), timestamp)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java index 232e1d1a763..8e3859d9134 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java @@ -101,7 +101,7 @@ private Predicate inJurisdictionOrOwned(CriteriaBuilder cb, CriteriaQuery cq, Fr protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Visit.CHANGE_DATE), timestamp)); } @@ -111,7 +111,7 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (maxChangeDatePeriod != null) { + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Visit.CHANGE_DATE), timestamp)); } From fbd2fa5b230d51b4d01e0ade465401d278bb3d52 Mon Sep 17 00:00:00 2001 From: Bal Andrei Date: Fri, 11 Nov 2022 16:23:19 +0200 Subject: [PATCH 003/166] #7305 Fix filter and revert refactoring - revert renaming of LIMITED_SYNCHRONIZATION feature in order to avoid data migration - add the new feature with LIMITED_MOBILE_SYNCHRONIZATION - use -1 as default/disabled value for newly added config - fix failing tests --- .../sormas/api/feature/FeatureType.java | 4 +-- .../sormas/backend/caze/CaseService.java | 18 +++++++------ .../clinicalcourse/ClinicalVisitService.java | 12 +++++---- ...oServiceWithUserFilterAndJurisdiction.java | 15 ++++++----- .../backend/contact/ContactService.java | 18 +++++++------ .../event/EventParticipantService.java | 12 +++++---- .../sormas/backend/event/EventService.java | 12 +++++---- .../immunization/ImmunizationService.java | 10 ++++--- .../sormas/backend/person/PersonService.java | 12 +++++---- .../report/AggregateReportService.java | 10 ++++--- .../backend/report/WeeklyReportService.java | 10 ++++--- .../backend/sample/AdditionalTestService.java | 12 +++++---- .../backend/sample/PathogenTestService.java | 12 +++++---- .../sormas/backend/sample/SampleService.java | 12 +++++---- .../sormas/backend/task/TaskService.java | 18 +++++++------ .../backend/therapy/PrescriptionService.java | 12 +++++---- .../backend/therapy/TreatmentService.java | 12 +++++---- .../sormas/backend/visit/VisitService.java | 12 +++++---- .../caze/CaseFacadeEjbUserFilterTest.java | 27 ++++++++++++++----- .../common/AdoServiceWithUserFilterTest.java | 2 +- 20 files changed, 150 insertions(+), 102 deletions(-) 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 d0ae97c6800..c649ef65350 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 @@ -72,8 +72,8 @@ public enum FeatureType { TRAVEL_ENTRIES(true, false, null, null, null), DASHBOARD(true, true, null, null, null), - EXCLUDE_NO_CASE_CLASSIFIED(true, false, null, null, ImmutableMap.of(FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES, Boolean.FALSE)), - LIMITED_SYNCHRONIZATION(true, false, null, null, ImmutableMap.of(FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, 30)), + LIMITED_SYNCHRONIZATION(true, false, null, null, ImmutableMap.of(FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES, Boolean.FALSE)), + LIMITED_MOBILE_SYNCHRONIZATION(true, false, null, null, ImmutableMap.of(FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, -1)), // FEATURE EXTENSIONS ASSIGN_TASKS_TO_HIGHER_LEVEL(true, 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 5e1fcca1499..e866427f4cd 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 @@ -260,8 +260,9 @@ public List findBy(CaseCriteria caseCriteria, boolean ignoreUserFilter) { @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Case.CHANGE_DATE), timestamp)); } @@ -271,8 +272,9 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From @Override protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Case.CHANGE_DATE), timestamp)); } @@ -321,7 +323,7 @@ public List getAllActiveUuids() { if (RequestContextHolder.isMobileSync()) { Predicate predicate = limitSynchronizationFilter(cb, from); if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, predicate); + filter = CriteriaBuilderHelper.and(cb, filter, predicate); } } @@ -586,9 +588,9 @@ public List getDeletedUuidsSince(Date since) { @Override protected List getAdditionalObsoleteUuidsPredicates(Date since, CriteriaBuilder cb, CriteriaQuery cq, Root from) { - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.EXCLUDE_NO_CASE_CLASSIFIED) + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && featureConfigurationFacade - .isPropertyValueTrue(FeatureType.EXCLUDE_NO_CASE_CLASSIFIED, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES)) { + .isPropertyValueTrue(FeatureType.LIMITED_SYNCHRONIZATION, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES)) { return Collections.singletonList(createObsoleteLimitedSyncCasePredicate(cb, from, since, getCurrentUser())); } else { return Collections.emptyList(); @@ -1454,7 +1456,7 @@ public Predicate createUserFilter(CaseQueryContext caseQueryContext, CaseUserFil if ((userFilterCriteria == null || !userFilterCriteria.isExcludeLimitedSyncRestrictions()) && featureConfigurationFacade - .isPropertyValueTrue(FeatureType.EXCLUDE_NO_CASE_CLASSIFIED, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES) + .isPropertyValueTrue(FeatureType.LIMITED_SYNCHRONIZATION, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES) && RequestContextHolder.isMobileSync()) { final Predicate limitedCaseSyncPredicate = cb.not( cb.and( diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java index 6b882c6e977..847e34b0113 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java @@ -85,8 +85,9 @@ protected void fetchReferences(From from) { @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(ClinicalVisit.CHANGE_DATE), timestamp)); } @@ -96,8 +97,9 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(ClinicalVisit.CHANGE_DATE), timestamp)); } @@ -122,7 +124,7 @@ public List getAllActiveUuids(User user) { if (RequestContextHolder.isMobileSync()) { Predicate predicate = limitSynchronizationFilter(cb, from); if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, predicate); + filter = CriteriaBuilderHelper.and(cb, filter, predicate); } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java index fbec31912c6..3f80e982a53 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java @@ -70,7 +70,7 @@ public List getAllAfter(Date since, Integer batchSize, String lastSynchroni if (RequestContextHolder.isMobileSync()) { Predicate predicate = limitSynchronizationFilter(cb, from); if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, predicate); + filter = CriteriaBuilderHelper.and(cb, filter, predicate); } } @@ -85,9 +85,12 @@ public List getAllUuids() { Root from = cq.from(getElementClass()); Predicate filter = createUserFilter(cb, cq, from); - Predicate predicate = limitSynchronizationFilter(cb, from); - if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, predicate); + if (RequestContextHolder.isMobileSync()) { + Predicate predicate = limitSynchronizationFilter(cb, from); + if (predicate != null) { + filter = CriteriaBuilderHelper.and(cb, filter, predicate); + } + } if (filter != null) { @@ -111,7 +114,7 @@ public List getAllIds(User user) { { Predicate predicate = limitSynchronizationFilter(cb, from); if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, predicate); + filter = CriteriaBuilderHelper.and(cb, filter, predicate); } } @@ -154,7 +157,7 @@ public List getObsoleteUuidsSince(Date since) { if (RequestContextHolder.isMobileSync()) { Predicate predicate = limitSynchronizationFilterObsoleteEntities(cb, from); if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, predicate); + filter = CriteriaBuilderHelper.or(cb, filter, predicate); } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java index d8b5cdf8c99..8e712fa6b30 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java @@ -204,8 +204,9 @@ public List findBy(ContactCriteria contactCriteria, User user) { @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Contact.CHANGE_DATE), timestamp)); } @@ -215,8 +216,9 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Contact.CHANGE_DATE), timestamp)); } @@ -293,7 +295,7 @@ public List getAllActiveUuids(User user) { if (RequestContextHolder.isMobileSync()) { Predicate predicate = limitSynchronizationFilter(cb, from); if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, predicate); + filter = CriteriaBuilderHelper.and(cb, filter, predicate); } } @@ -515,9 +517,9 @@ public List getDeletedUuidsSince(User user, Date since) { @Override protected List getAdditionalObsoleteUuidsPredicates(Date since, CriteriaBuilder cb, CriteriaQuery cq, Root from) { - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.EXCLUDE_NO_CASE_CLASSIFIED) + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && featureConfigurationFacade - .isPropertyValueTrue(FeatureType.EXCLUDE_NO_CASE_CLASSIFIED, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES)) { + .isPropertyValueTrue(FeatureType.LIMITED_SYNCHRONIZATION, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES)) { ContactQueryContext contactQueryContext = new ContactQueryContext(cb, cq, from); return Collections.singletonList( @@ -1131,7 +1133,7 @@ public Predicate createUserFilterWithoutCase(ContactQueryContext qc, ContactCrit if ((contactCriteria == null || !contactCriteria.isExcludeLimitedSyncRestrictions()) && featureConfigurationFacade - .isPropertyValueTrue(FeatureType.EXCLUDE_NO_CASE_CLASSIFIED, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES) + .isPropertyValueTrue(FeatureType.LIMITED_SYNCHRONIZATION, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES) && RequestContextHolder.isMobileSync()) { final Predicate limitedCaseSyncPredicate = caseService.createLimitedSyncCasePredicate(cb, qc.getJoins().getCaze(), currentUser); filter = CriteriaBuilderHelper.and(cb, filter, limitedCaseSyncPredicate); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java index 0efab7c968c..83811f42a86 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java @@ -110,8 +110,9 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(EventParticipant.CHANGE_DATE), timestamp)); } @@ -121,8 +122,9 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(EventParticipant.CHANGE_DATE), timestamp)); } @@ -150,7 +152,7 @@ public List getAllActiveUuids(User user) { if (RequestContextHolder.isMobileSync()) { Predicate predicate = limitSynchronizationFilter(cb, from); if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, predicate); + filter = CriteriaBuilderHelper.and(cb, filter, predicate); } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java index 635f391dbd6..c0ddb154be6 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java @@ -170,8 +170,9 @@ protected void fetchReferences(From from) { @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Event.CHANGE_DATE), timestamp)); } @@ -181,8 +182,9 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Event.CHANGE_DATE), timestamp)); } @@ -212,7 +214,7 @@ public List getAllActiveUuids() { if (RequestContextHolder.isMobileSync()) { Predicate predicate = limitSynchronizationFilter(cb, from); if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, predicate); + filter = CriteriaBuilderHelper.and(cb, filter, predicate); } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java index 564de16885b..3702c041bc9 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java @@ -121,8 +121,9 @@ public void deletePermanent(Immunization immunization) { @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Immunization.CHANGE_DATE), timestamp)); } @@ -132,8 +133,9 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Immunization.CHANGE_DATE), timestamp)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java index bc67c224b4e..c8429541042 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java @@ -195,8 +195,9 @@ private boolean isPermitted(FeatureType featureType, UserRight userRight) { @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Person.CHANGE_DATE), timestamp)); } @@ -206,8 +207,9 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Person.CHANGE_DATE), timestamp)); } @@ -593,7 +595,7 @@ private List getAllAfter( if (RequestContextHolder.isMobileSync()) { Predicate predicate = limitSynchronizationFilter(cb, personJoin); if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, predicate); + filter = CriteriaBuilderHelper.and(cb, filter, predicate); } } if (filter != null) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java index c6dd93efecb..ce281616d2f 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java @@ -190,8 +190,9 @@ public Predicate createUserFilter(AggregateReportQueryContext queryContext) { @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(AggregateReport.CHANGE_DATE), timestamp)); } @@ -201,8 +202,9 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(AggregateReport.CHANGE_DATE), timestamp)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java index 3f0657b767b..5461d223c66 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java @@ -124,8 +124,9 @@ public WeeklyReport getByEpiWeekAndUser(EpiWeek epiWeek, User user) { @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(WeeklyReport.CHANGE_DATE), timestamp)); } @@ -135,8 +136,9 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(WeeklyReport.CHANGE_DATE), timestamp)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java index def1166f833..3b4240f94f8 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java @@ -66,8 +66,9 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(AdditionalTest.CHANGE_DATE), timestamp)); } @@ -77,8 +78,9 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(AdditionalTest.CHANGE_DATE), timestamp)); } @@ -174,7 +176,7 @@ public List getAllActiveUuids(User user) { if (RequestContextHolder.isMobileSync()) { Predicate predicate = limitSynchronizationFilter(cb, from); if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, predicate); + filter = CriteriaBuilderHelper.and(cb, filter, predicate); } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java index 3a3f9cad82f..9ad830f2068 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java @@ -88,8 +88,9 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(PathogenTest.CHANGE_DATE), timestamp)); } @@ -99,8 +100,9 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(PathogenTest.CHANGE_DATE), timestamp)); } @@ -123,7 +125,7 @@ public List getAllActiveUuids(User user) { if (RequestContextHolder.isMobileSync()) { Predicate predicate = limitSynchronizationFilter(cb, from); if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, predicate); + filter = CriteriaBuilderHelper.and(cb, filter, predicate); } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java index 28922613818..4a5f4fb49f2 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java @@ -393,8 +393,9 @@ public List getIndexList(SampleCriteria sampleCriteria, Integer @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Sample.CHANGE_DATE), timestamp)); } @@ -404,8 +405,9 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Sample.CHANGE_DATE), timestamp)); } @@ -502,7 +504,7 @@ public List getAllActiveUuids(User user) { if (RequestContextHolder.isMobileSync()) { Predicate predicate = limitSynchronizationFilter(cb, from); if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, predicate); + filter = CriteriaBuilderHelper.and(cb, filter, predicate); } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java index 671c06a94f3..6131cb37592 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java @@ -125,8 +125,9 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Task.CHANGE_DATE), timestamp)); } @@ -136,8 +137,9 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From @Override protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Task.CHANGE_DATE), timestamp)); } @@ -161,7 +163,7 @@ public List getAllActiveUuids(User user) { if (RequestContextHolder.isMobileSync()) { Predicate predicate = limitSynchronizationFilter(cb, from); if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, predicate); + filter = CriteriaBuilderHelper.and(cb, filter, predicate); } } @@ -276,7 +278,7 @@ public Predicate createUserFilter(TaskQueryContext taskQueryContext, TaskCriteri if ((taskCriteria == null || !taskCriteria.isExcludeLimitedSyncRestrictions()) && featureConfigurationFacade - .isPropertyValueTrue(FeatureType.EXCLUDE_NO_CASE_CLASSIFIED, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES) + .isPropertyValueTrue(FeatureType.LIMITED_SYNCHRONIZATION, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES) && RequestContextHolder.isMobileSync()) { Predicate limitedCaseSyncPredicate = CriteriaBuilderHelper.and( @@ -293,9 +295,9 @@ public Predicate createUserFilter(TaskQueryContext taskQueryContext, TaskCriteri @Override protected List getAdditionalObsoleteUuidsPredicates(Date since, CriteriaBuilder cb, CriteriaQuery cq, Root from) { - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.EXCLUDE_NO_CASE_CLASSIFIED) + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && featureConfigurationFacade - .isPropertyValueTrue(FeatureType.EXCLUDE_NO_CASE_CLASSIFIED, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES)) { + .isPropertyValueTrue(FeatureType.LIMITED_SYNCHRONIZATION, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES)) { List predicates = new ArrayList<>(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java index 21b8421febc..df2fcd9e485 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java @@ -81,8 +81,9 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Prescription.CHANGE_DATE), timestamp)); } @@ -92,8 +93,9 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Prescription.CHANGE_DATE), timestamp)); } @@ -118,7 +120,7 @@ public List getAllActiveUuids(User user) { if (RequestContextHolder.isMobileSync()) { Predicate predicate = limitSynchronizationFilter(cb, from); if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, predicate); + filter = CriteriaBuilderHelper.and(cb, filter, predicate); } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java index c2bfcd0921b..99dbffbbddb 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java @@ -81,8 +81,9 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Treatment.CHANGE_DATE), timestamp)); } @@ -92,8 +93,9 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Treatment.CHANGE_DATE), timestamp)); } @@ -118,7 +120,7 @@ public List getAllActiveUuids(User user) { if (RequestContextHolder.isMobileSync()) { Predicate predicate = limitSynchronizationFilter(cb, from); if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, predicate); + filter = CriteriaBuilderHelper.and(cb, filter, predicate); } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java index 8e3859d9134..003c5d13748 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java @@ -100,8 +100,9 @@ private Predicate inJurisdictionOrOwned(CriteriaBuilder cb, CriteriaQuery cq, Fr protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Visit.CHANGE_DATE), timestamp)); } @@ -110,8 +111,9 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null) { + .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Visit.CHANGE_DATE), timestamp)); } @@ -203,7 +205,7 @@ public List getAllAfter(Date since, Integer batchSize, String lastSynchro if (RequestContextHolder.isMobileSync()) { Predicate predicate = limitSynchronizationFilter(cb, from); if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, predicate); + filter = CriteriaBuilderHelper.and(cb, filter, predicate); } } return filter; diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbUserFilterTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbUserFilterTest.java index 425f7bd3c31..ec011c7947e 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbUserFilterTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbUserFilterTest.java @@ -143,19 +143,32 @@ public void init() { } @Test - public void testGetCasesWithLimitedSynchronization() { + public void testGetCasesWithExcludeNoCaseClassifiedAndMaxChangedDate() { FeatureConfigurationIndexDto featureConfiguration = new FeatureConfigurationIndexDto(DataHelper.createUuid(), null, null, null, null, null, true, null); - getFeatureConfigurationFacade().saveFeatureConfiguration(featureConfiguration, FeatureType.EXCLUDE_NO_CASE_CLASSIFIED); + getFeatureConfigurationFacade().saveFeatureConfiguration(featureConfiguration, FeatureType.LIMITED_SYNCHRONIZATION); + FeatureConfigurationIndexDto featureConfigurationMaxChangeDate = + new FeatureConfigurationIndexDto(DataHelper.createUuid(), null, null, null, null, null, true, null); + getFeatureConfigurationFacade().saveFeatureConfiguration(featureConfigurationMaxChangeDate, FeatureType.LIMITED_MOBILE_SYNCHRONIZATION); SessionImpl em = (SessionImpl) getEntityManager(); QueryImplementor query = em.createQuery("select f from featureconfiguration f"); - FeatureConfiguration singleResult = (FeatureConfiguration) query.getSingleResult(); - HashMap properties = new HashMap<>(); - properties.put(FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES, true); - singleResult.setProperties(properties); - em.save(singleResult); + List results = (List) query.getResultList(); + HashMap excludeNoCaseClassifiedProperties = new HashMap<>(); + excludeNoCaseClassifiedProperties.put(FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES, true); + HashMap maxChangeDateProperties = new HashMap<>(); + int maxChangeDateOffset = 30; + maxChangeDateProperties.put(FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, maxChangeDateOffset); + + results.forEach(fc -> { + if (fc.getFeatureType().equals(FeatureType.LIMITED_SYNCHRONIZATION)) { + fc.setProperties(excludeNoCaseClassifiedProperties); + } else { + fc.setProperties(maxChangeDateProperties); + } + em.save(fc); + }); MockProducer.setMobileSync(true); diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterTest.java index e0a48d7e709..196f57a5504 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterTest.java @@ -34,7 +34,7 @@ public void testGetObsoleteUuidsSince() { FeatureConfigurationIndexDto featureConfiguration = new FeatureConfigurationIndexDto(DataHelper.createUuid(), null, null, null, null, null, true, null); - getFeatureConfigurationFacade().saveFeatureConfiguration(featureConfiguration, FeatureType.EXCLUDE_NO_CASE_CLASSIFIED); + getFeatureConfigurationFacade().saveFeatureConfiguration(featureConfiguration, FeatureType.LIMITED_SYNCHRONIZATION); SessionImpl em = (SessionImpl) getEntityManager(); QueryImplementor query = em.createQuery("select f from featureconfiguration f"); From 3c477e807b661cf0a09c0f3831211da85bcaf3bc Mon Sep 17 00:00:00 2001 From: Bal Andrei Date: Mon, 14 Nov 2022 14:09:56 +0200 Subject: [PATCH 004/166] #7305 Add new feature type property to LIMITED_SYNCHRONIZATION - instead of adding a new feature configuration, add the the newly added feature type property to the existing LIMITED_SYNCHRONIZATION feature configuration --- .../java/de/symeda/sormas/api/feature/FeatureType.java | 3 +-- .../de/symeda/sormas/api/feature/FeatureTypeProperty.java | 2 +- .../java/de/symeda/sormas/backend/caze/CaseService.java | 8 ++++---- .../backend/clinicalcourse/ClinicalVisitService.java | 8 ++++---- .../de/symeda/sormas/backend/contact/ContactService.java | 8 ++++---- .../sormas/backend/event/EventParticipantService.java | 8 ++++---- .../java/de/symeda/sormas/backend/event/EventService.java | 8 ++++---- .../sormas/backend/immunization/ImmunizationService.java | 8 ++++---- .../de/symeda/sormas/backend/person/PersonService.java | 8 ++++---- .../sormas/backend/report/AggregateReportService.java | 8 ++++---- .../symeda/sormas/backend/report/WeeklyReportService.java | 8 ++++---- .../sormas/backend/sample/AdditionalTestService.java | 8 ++++---- .../symeda/sormas/backend/sample/PathogenTestService.java | 8 ++++---- .../de/symeda/sormas/backend/sample/SampleService.java | 8 ++++---- .../java/de/symeda/sormas/backend/task/TaskService.java | 8 ++++---- .../sormas/backend/therapy/PrescriptionService.java | 8 ++++---- .../symeda/sormas/backend/therapy/TreatmentService.java | 8 ++++---- .../java/de/symeda/sormas/backend/visit/VisitService.java | 8 ++++---- .../sormas/backend/caze/CaseFacadeEjbUserFilterTest.java | 4 ++-- 19 files changed, 68 insertions(+), 69 deletions(-) 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 c649ef65350..97d7bebbb54 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 @@ -72,8 +72,7 @@ public enum FeatureType { TRAVEL_ENTRIES(true, false, null, null, null), DASHBOARD(true, true, null, null, null), - LIMITED_SYNCHRONIZATION(true, false, null, null, ImmutableMap.of(FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES, Boolean.FALSE)), - LIMITED_MOBILE_SYNCHRONIZATION(true, false, null, null, ImmutableMap.of(FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, -1)), + LIMITED_SYNCHRONIZATION(true, false, null, null, ImmutableMap.of(FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES, Boolean.FALSE, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, -1)), // FEATURE EXTENSIONS ASSIGN_TASKS_TO_HIGHER_LEVEL(true, 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 612abb42708..5e50f4460ad 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 @@ -23,7 +23,7 @@ public enum FeatureTypeProperty { ALLOW_FREE_EDITING(Boolean.class), THRESHOLD_IN_DAYS(Integer.class), EXCLUDE_NO_CASE_CLASSIFIED_CASES(Boolean.class), - MAX_CHANGEDATE_SYNCHRONIZATION(Integer.class), + MAX_CHANGE_DATE_SYNCHRONIZATION(Integer.class), S2S_SHARING(Boolean.class), SHARE_ASSOCIATED_CONTACTS(Boolean.class), SHARE_SAMPLES(Boolean.class), 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 e866427f4cd..89cd7b17463 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 @@ -260,8 +260,8 @@ public List findBy(CaseCriteria caseCriteria, boolean ignoreUserFilter) { @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Case.CHANGE_DATE), timestamp)); @@ -272,8 +272,8 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From @Override protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Case.CHANGE_DATE), timestamp)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java index 847e34b0113..e8f996bb7fe 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java @@ -85,8 +85,8 @@ protected void fetchReferences(From from) { @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(ClinicalVisit.CHANGE_DATE), timestamp)); @@ -97,8 +97,8 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(ClinicalVisit.CHANGE_DATE), timestamp)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java index 8e712fa6b30..007db4790c2 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java @@ -204,8 +204,8 @@ public List findBy(ContactCriteria contactCriteria, User user) { @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Contact.CHANGE_DATE), timestamp)); @@ -216,8 +216,8 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Contact.CHANGE_DATE), timestamp)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java index 83811f42a86..43ae2bc9426 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java @@ -110,8 +110,8 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(EventParticipant.CHANGE_DATE), timestamp)); @@ -122,8 +122,8 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(EventParticipant.CHANGE_DATE), timestamp)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java index c0ddb154be6..9b77a92305d 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java @@ -170,8 +170,8 @@ protected void fetchReferences(From from) { @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Event.CHANGE_DATE), timestamp)); @@ -182,8 +182,8 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Event.CHANGE_DATE), timestamp)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java index 3702c041bc9..baf23067a33 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java @@ -121,8 +121,8 @@ public void deletePermanent(Immunization immunization) { @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Immunization.CHANGE_DATE), timestamp)); @@ -133,8 +133,8 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Immunization.CHANGE_DATE), timestamp)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java index c8429541042..9e301d6edae 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java @@ -195,8 +195,8 @@ private boolean isPermitted(FeatureType featureType, UserRight userRight) { @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Person.CHANGE_DATE), timestamp)); @@ -207,8 +207,8 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Person.CHANGE_DATE), timestamp)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java index ce281616d2f..6b793b63a9a 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java @@ -190,8 +190,8 @@ public Predicate createUserFilter(AggregateReportQueryContext queryContext) { @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(AggregateReport.CHANGE_DATE), timestamp)); @@ -202,8 +202,8 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(AggregateReport.CHANGE_DATE), timestamp)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java index 5461d223c66..0d35a14ab8f 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java @@ -124,8 +124,8 @@ public WeeklyReport getByEpiWeekAndUser(EpiWeek epiWeek, User user) { @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(WeeklyReport.CHANGE_DATE), timestamp)); @@ -136,8 +136,8 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(WeeklyReport.CHANGE_DATE), timestamp)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java index 3b4240f94f8..31eac11ca5c 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java @@ -66,8 +66,8 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(AdditionalTest.CHANGE_DATE), timestamp)); @@ -78,8 +78,8 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(AdditionalTest.CHANGE_DATE), timestamp)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java index 9ad830f2068..512c1c499bf 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java @@ -88,8 +88,8 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(PathogenTest.CHANGE_DATE), timestamp)); @@ -100,8 +100,8 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(PathogenTest.CHANGE_DATE), timestamp)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java index 4a5f4fb49f2..05d0b46ccf4 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java @@ -393,8 +393,8 @@ public List getIndexList(SampleCriteria sampleCriteria, Integer @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Sample.CHANGE_DATE), timestamp)); @@ -405,8 +405,8 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Sample.CHANGE_DATE), timestamp)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java index 6131cb37592..a81e1b931a9 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java @@ -125,8 +125,8 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Task.CHANGE_DATE), timestamp)); @@ -137,8 +137,8 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From @Override protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Task.CHANGE_DATE), timestamp)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java index df2fcd9e485..5131b77df92 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java @@ -81,8 +81,8 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Prescription.CHANGE_DATE), timestamp)); @@ -93,8 +93,8 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Prescription.CHANGE_DATE), timestamp)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java index 99dbffbbddb..8f4e1b3bd60 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java @@ -81,8 +81,8 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c @Override protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Treatment.CHANGE_DATE), timestamp)); @@ -93,8 +93,8 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Treatment.CHANGE_DATE), timestamp)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java index 003c5d13748..9128730d95d 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java @@ -100,8 +100,8 @@ private Predicate inJurisdictionOrOwned(CriteriaBuilder cb, CriteriaQuery cq, Fr protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Visit.CHANGE_DATE), timestamp)); @@ -111,8 +111,8 @@ protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_MOBILE_SYNCHRONIZATION) + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Visit.CHANGE_DATE), timestamp)); diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbUserFilterTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbUserFilterTest.java index ec011c7947e..57f18552fb5 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbUserFilterTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbUserFilterTest.java @@ -150,7 +150,7 @@ public void testGetCasesWithExcludeNoCaseClassifiedAndMaxChangedDate() { getFeatureConfigurationFacade().saveFeatureConfiguration(featureConfiguration, FeatureType.LIMITED_SYNCHRONIZATION); FeatureConfigurationIndexDto featureConfigurationMaxChangeDate = new FeatureConfigurationIndexDto(DataHelper.createUuid(), null, null, null, null, null, true, null); - getFeatureConfigurationFacade().saveFeatureConfiguration(featureConfigurationMaxChangeDate, FeatureType.LIMITED_MOBILE_SYNCHRONIZATION); + getFeatureConfigurationFacade().saveFeatureConfiguration(featureConfigurationMaxChangeDate, FeatureType.LIMITED_SYNCHRONIZATION); SessionImpl em = (SessionImpl) getEntityManager(); QueryImplementor query = em.createQuery("select f from featureconfiguration f"); @@ -159,7 +159,7 @@ public void testGetCasesWithExcludeNoCaseClassifiedAndMaxChangedDate() { excludeNoCaseClassifiedProperties.put(FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES, true); HashMap maxChangeDateProperties = new HashMap<>(); int maxChangeDateOffset = 30; - maxChangeDateProperties.put(FeatureTypeProperty.MAX_CHANGEDATE_SYNCHRONIZATION, maxChangeDateOffset); + maxChangeDateProperties.put(FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, maxChangeDateOffset); results.forEach(fc -> { if (fc.getFeatureType().equals(FeatureType.LIMITED_SYNCHRONIZATION)) { From 9138537200e6f161ad92144c8159fcfdd99c3568 Mon Sep 17 00:00:00 2001 From: Bal Andrei Date: Wed, 16 Nov 2022 17:45:53 +0200 Subject: [PATCH 005/166] #7305 Move new filter to higher hierarchy level - revisit entities that should not be synchronized --- .../sormas/backend/action/ActionService.java | 10 +++++ .../backend/campaign/CampaignService.java | 10 +++++ .../data/CampaignFormDataService.java | 10 +++++ .../CampaignDiagramDefinitionService.java | 10 +++++ .../form/CampaignFormMetaService.java | 10 +++++ .../sormas/backend/caze/CaseService.java | 26 +---------- .../SurveillanceReportService.java | 10 +++++ .../clinicalcourse/ClinicalVisitService.java | 43 +++++-------------- .../AbstractInfrastructureAdoService.java | 11 +++++ ...oServiceWithUserFilterAndJurisdiction.java | 36 +++++++++++++--- .../backend/contact/ContactService.java | 26 +---------- .../CustomizableEnumValueService.java | 10 +++++ .../disease/DiseaseConfigurationService.java | 10 +++++ .../backend/document/DocumentService.java | 10 +++++ .../backend/event/EventGroupService.java | 10 +++++ .../event/EventParticipantService.java | 25 ++--------- .../sormas/backend/event/EventService.java | 31 +------------ .../ExternalMessageService.java | 10 +++++ .../feature/FeatureConfigurationService.java | 10 +++++ .../DirectoryImmunizationService.java | 10 +++++ .../immunization/ImmunizationService.java | 24 ----------- .../infrastructure/PopulationDataService.java | 10 +++++ .../backend/outbreak/OutbreakService.java | 10 +++++ .../sormas/backend/person/PersonService.java | 36 +++++----------- .../report/AggregateReportService.java | 42 +++++------------- .../report/WeeklyReportEntryService.java | 10 +++++ .../backend/report/WeeklyReportService.java | 42 +++++------------- .../backend/sample/AdditionalTestService.java | 28 ++---------- .../backend/sample/PathogenTestService.java | 26 ++--------- .../sormas/backend/sample/SampleService.java | 27 +----------- .../share/ExternalShareInfoService.java | 10 +++++ .../SormasToSormasOriginInfoService.java | 10 +++++ .../SormasToSormasShareRequestService.java | 10 +++++ .../outgoing/ShareRequestInfoService.java | 10 +++++ .../SormasToSormasShareInfoService.java | 10 +++++ .../sormas/backend/task/TaskService.java | 27 +----------- .../backend/therapy/PrescriptionService.java | 29 ++----------- .../backend/therapy/TreatmentService.java | 28 ++---------- .../services/BaseTravelEntryService.java | 10 +++++ .../services/TravelEntryService.java | 1 - .../sormas/backend/user/UserRoleService.java | 10 +++++ .../sormas/backend/user/UserService.java | 10 +++++ .../vaccination/VaccinationService.java | 10 +++++ .../sormas/backend/visit/VisitService.java | 36 ++++------------ .../caze/CaseFacadeEjbUserFilterTest.java | 24 +++-------- 45 files changed, 369 insertions(+), 449 deletions(-) diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/action/ActionService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/action/ActionService.java index f4bad5c2b15..b387553c75d 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/action/ActionService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/action/ActionService.java @@ -74,6 +74,16 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c return filter; } + @Override + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public List getAllActiveUuids() { CriteriaBuilder cb = em.getCriteriaBuilder(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java index 15d77cd4416..89e4b044a8f 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java @@ -31,6 +31,16 @@ protected Predicate createUserFilterInternal(CriteriaBuilder cb, CriteriaQuery c return createUserFilter(new CampaignQueryContext(cb, cq, from)); } + @Override + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public Predicate createUserFilter(CampaignQueryContext queryContext) { // A user who has access to CampaignView can read all campaigns return null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/data/CampaignFormDataService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/data/CampaignFormDataService.java index cbd82be2871..daf64ecb154 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/data/CampaignFormDataService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/data/CampaignFormDataService.java @@ -130,6 +130,16 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public List getAllActiveUuids() { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cq = cb.createQuery(String.class); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/diagram/CampaignDiagramDefinitionService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/diagram/CampaignDiagramDefinitionService.java index a534247465c..4ff47e3995e 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/diagram/CampaignDiagramDefinitionService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/diagram/CampaignDiagramDefinitionService.java @@ -26,6 +26,16 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public boolean diagramExists(@NotNull String diagramId) { return exists((cb, root, cq) -> cb.equal(root.get(CampaignDiagramDefinition.DIAGRAM_ID), diagramId)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/form/CampaignFormMetaService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/form/CampaignFormMetaService.java index 143a4ec05f7..d52ef82a01c 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/form/CampaignFormMetaService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/form/CampaignFormMetaService.java @@ -29,6 +29,16 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public List getCampaignFormMetasAsReferencesByCampaign(String uuid) { CriteriaBuilder cb = em.getCriteriaBuilder(); 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 89cd7b17463..09f03eded8f 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 @@ -257,30 +257,6 @@ public List findBy(CaseCriteria caseCriteria, boolean ignoreUserFilter) { return em.createQuery(cq).getResultList(); } - @Override - protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Case.CHANGE_DATE), timestamp)); - } - return null; - } - - @Override - protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Case.CHANGE_DATE), timestamp)); - } - return null; - } - @Override @SuppressWarnings("rawtypes") protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { @@ -321,7 +297,7 @@ public List getAllActiveUuids() { } if (RequestContextHolder.isMobileSync()) { - Predicate predicate = limitSynchronizationFilter(cb, from); + Predicate predicate = createLimitedChangeDateFilter(cb, from); if (predicate != null) { filter = CriteriaBuilderHelper.and(cb, filter, predicate); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportService.java index 1921730d928..82214f1d8c1 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportService.java @@ -83,6 +83,16 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + @Override public boolean inJurisdictionOrOwned(SurveillanceReport entity) { return fulfillsCondition(entity, this::inJurisdictionOrOwned); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java index e8f996bb7fe..b6771f0c23c 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java @@ -1,7 +1,6 @@ package de.symeda.sormas.backend.clinicalcourse; import java.sql.Timestamp; -import java.util.Date; import java.util.List; import javax.ejb.EJB; @@ -17,9 +16,6 @@ import de.symeda.sormas.api.RequestContextHolder; import de.symeda.sormas.api.clinicalcourse.ClinicalVisitCriteria; -import de.symeda.sormas.api.feature.FeatureType; -import de.symeda.sormas.api.feature.FeatureTypeProperty; -import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.caze.CaseJoins; import de.symeda.sormas.backend.caze.CaseQueryContext; @@ -27,7 +23,6 @@ import de.symeda.sormas.backend.common.AdoServiceWithUserFilterAndJurisdiction; import de.symeda.sormas.backend.common.ChangeDateFilterBuilder; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; -import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import de.symeda.sormas.backend.symptoms.Symptoms; import de.symeda.sormas.backend.user.User; @@ -37,13 +32,21 @@ public class ClinicalVisitService extends AdoServiceWithUserFilterAndJurisdictio @EJB private CaseService caseService; - @EJB - protected FeatureConfigurationFacadeEjb.FeatureConfigurationFacadeEjbLocal featureConfigurationFacade; public ClinicalVisitService() { super(ClinicalVisit.class); } + @Override + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public List findBy(ClinicalVisitCriteria criteria) { CriteriaBuilder cb = em.getCriteriaBuilder(); @@ -82,30 +85,6 @@ protected void fetchReferences(From from) { from.fetch(ClinicalVisit.SYMPTOMS); } - @Override - protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(ClinicalVisit.CHANGE_DATE), timestamp)); - } - return null; - } - - @Override - protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(ClinicalVisit.CHANGE_DATE), timestamp)); - } - return null; - } - public List getAllActiveUuids(User user) { CriteriaBuilder cb = em.getCriteriaBuilder(); @@ -122,7 +101,7 @@ public List getAllActiveUuids(User user) { } if (RequestContextHolder.isMobileSync()) { - Predicate predicate = limitSynchronizationFilter(cb, from); + Predicate predicate = createLimitedChangeDateFilter(cb, from); if (predicate != null) { filter = CriteriaBuilderHelper.and(cb, filter, predicate); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractInfrastructureAdoService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractInfrastructureAdoService.java index a836116daf2..5cb711ee55c 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractInfrastructureAdoService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractInfrastructureAdoService.java @@ -6,6 +6,7 @@ import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.From; import javax.persistence.criteria.Join; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; @@ -32,6 +33,16 @@ public Predicate createBasicFilter(CriteriaBuilder cb, Root root) { return cb.isFalse(root.get(InfrastructureAdo.ARCHIVED)); } + @Override + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public List getAllActive() { CriteriaBuilder cb = em.getCriteriaBuilder(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java index 3f80e982a53..6015eb61a99 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java @@ -1,9 +1,11 @@ package de.symeda.sormas.backend.common; +import java.sql.Timestamp; import java.util.Collections; import java.util.Date; import java.util.List; +import javax.ejb.EJB; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Expression; @@ -12,6 +14,10 @@ import javax.persistence.criteria.Root; import de.symeda.sormas.api.RequestContextHolder; +import de.symeda.sormas.api.feature.FeatureType; +import de.symeda.sormas.api.feature.FeatureTypeProperty; +import de.symeda.sormas.api.utils.DateHelper; +import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import org.apache.commons.lang3.StringUtils; import de.symeda.sormas.backend.user.User; @@ -25,6 +31,8 @@ public abstract class AdoServiceWithUserFilterAndJurisdiction extends BaseAdoService { public static final int NR_OF_LAST_PHONE_DIGITS_TO_SEARCH = 6; + @EJB + protected FeatureConfigurationFacadeEjb.FeatureConfigurationFacadeEjbLocal featureConfigurationFacade; protected AdoServiceWithUserFilterAndJurisdiction(Class elementClass) { super(elementClass); @@ -36,11 +44,27 @@ protected AdoServiceWithUserFilterAndJurisdiction(Class elementClass) { @SuppressWarnings("rawtypes") public abstract Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from); - protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { + Date maxChangeDate = DateHelper.subtractDays(new Date(), maxChangeDatePeriod); + Timestamp timestamp = Timestamp.from(DateHelper.getStartOfDay(maxChangeDate).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(ADO.CHANGE_DATE), timestamp)); + } return null; } - protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + final Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) + && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { + Date maxChangeDate = DateHelper.subtractDays(new Date(), maxChangeDatePeriod); + Timestamp timestamp = Timestamp.from(DateHelper.getStartOfDay(maxChangeDate).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(ADO.CHANGE_DATE), timestamp)); + } return null; } @@ -68,7 +92,7 @@ public List getAllAfter(Date since, Integer batchSize, String lastSynchroni } if (RequestContextHolder.isMobileSync()) { - Predicate predicate = limitSynchronizationFilter(cb, from); + Predicate predicate = createLimitedChangeDateFilter(cb, from); if (predicate != null) { filter = CriteriaBuilderHelper.and(cb, filter, predicate); } @@ -86,7 +110,7 @@ public List getAllUuids() { Predicate filter = createUserFilter(cb, cq, from); if (RequestContextHolder.isMobileSync()) { - Predicate predicate = limitSynchronizationFilter(cb, from); + Predicate predicate = createLimitedChangeDateFilter(cb, from); if (predicate != null) { filter = CriteriaBuilderHelper.and(cb, filter, predicate); } @@ -112,7 +136,7 @@ public List getAllIds(User user) { if (RequestContextHolder.isMobileSync()) { - Predicate predicate = limitSynchronizationFilter(cb, from); + Predicate predicate = createLimitedChangeDateFilter(cb, from); if (predicate != null) { filter = CriteriaBuilderHelper.and(cb, filter, predicate); } @@ -155,7 +179,7 @@ public List getObsoleteUuidsSince(Date since) { filter = CriteriaBuilderHelper.and(cb, filter, contentFilter); if (RequestContextHolder.isMobileSync()) { - Predicate predicate = limitSynchronizationFilterObsoleteEntities(cb, from); + Predicate predicate = createLimitedChangeDateFilterForObsoleteEntities(cb, from); if (predicate != null) { filter = CriteriaBuilderHelper.or(cb, filter, predicate); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java index 007db4790c2..257050fca52 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java @@ -201,30 +201,6 @@ public List findBy(ContactCriteria contactCriteria, User user) { return em.createQuery(cq).getResultList(); } - @Override - protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Contact.CHANGE_DATE), timestamp)); - } - return null; - } - - @Override - protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Contact.CHANGE_DATE), timestamp)); - } - return null; - } - @Override @SuppressWarnings("rawtypes") protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { @@ -293,7 +269,7 @@ public List getAllActiveUuids(User user) { } if (RequestContextHolder.isMobileSync()) { - Predicate predicate = limitSynchronizationFilter(cb, from); + Predicate predicate = createLimitedChangeDateFilter(cb, from); if (predicate != null) { filter = CriteriaBuilderHelper.and(cb, filter, predicate); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/customizableenum/CustomizableEnumValueService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/customizableenum/CustomizableEnumValueService.java index e45cbc2dad0..04ed9445b39 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/customizableenum/CustomizableEnumValueService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/customizableenum/CustomizableEnumValueService.java @@ -37,4 +37,14 @@ public CustomizableEnumValueService() { public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { return null; } + + @Override + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/disease/DiseaseConfigurationService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/disease/DiseaseConfigurationService.java index a11b895efec..300dc3c1808 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/disease/DiseaseConfigurationService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/disease/DiseaseConfigurationService.java @@ -56,4 +56,14 @@ public Subquery existActiveDisease(CriteriaQuery cq, CriteriaBuilder cb, R public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { return null; } + + @Override + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/document/DocumentService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/document/DocumentService.java index 70132b8b992..6e9a6f5f1b6 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/document/DocumentService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/document/DocumentService.java @@ -47,6 +47,16 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public void markAsDeleted(Document deleteme) { deleteme.setDeleted(true); em.persist(deleteme); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventGroupService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventGroupService.java index 3fafadb7bbe..e4f4bc9decc 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventGroupService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventGroupService.java @@ -66,6 +66,16 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + @SuppressWarnings("rawtypes") public Predicate createUserFilter( CriteriaBuilder cb, diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java index 43ae2bc9426..397cf38a5ba 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java @@ -44,8 +44,6 @@ import de.symeda.sormas.api.caze.VaccinationStatus; import de.symeda.sormas.api.common.DeletionDetails; import de.symeda.sormas.api.event.EventParticipantCriteria; -import de.symeda.sormas.api.feature.FeatureType; -import de.symeda.sormas.api.feature.FeatureTypeProperty; import de.symeda.sormas.api.utils.DataHelper; import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.backend.common.AbstractCoreAdoService; @@ -54,7 +52,6 @@ import de.symeda.sormas.backend.common.ChangeDateFilterBuilder; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; import de.symeda.sormas.backend.contact.Contact; -import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import de.symeda.sormas.backend.person.Person; import de.symeda.sormas.backend.person.PersonQueryContext; import de.symeda.sormas.backend.sample.Sample; @@ -80,8 +77,6 @@ public class EventParticipantService extends AbstractCoreAdoService from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(EventParticipant.CHANGE_DATE), timestamp)); - } + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; } @Override - protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(EventParticipant.CHANGE_DATE), timestamp)); - } + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { return null; } @@ -150,7 +131,7 @@ public List getAllActiveUuids(User user) { } if (RequestContextHolder.isMobileSync()) { - Predicate predicate = limitSynchronizationFilter(cb, from); + Predicate predicate = createLimitedChangeDateFilter(cb, from); if (predicate != null) { filter = CriteriaBuilderHelper.and(cb, filter, predicate); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java index 9b77a92305d..f7245d24b6a 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java @@ -41,9 +41,6 @@ import javax.transaction.Transactional; import de.symeda.sormas.api.RequestContextHolder; -import de.symeda.sormas.api.feature.FeatureType; -import de.symeda.sormas.api.feature.FeatureTypeProperty; -import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -135,8 +132,6 @@ public class EventService extends AbstractCoreAdoService { private EventFacadeEjb.EventFacadeEjbLocal eventFacade; @EJB private ExternalSurveillanceToolGatewayFacadeEjb.ExternalSurveillanceToolGatewayFacadeEjbLocal externalSurveillanceToolGatewayFacade; - @EJB - protected FeatureConfigurationFacadeEjb.FeatureConfigurationFacadeEjbLocal featureConfigurationFacade; public EventService() { super(Event.class); @@ -167,30 +162,6 @@ protected void fetchReferences(From from) { from.fetch(Event.EVENT_LOCATION); } - @Override - protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Event.CHANGE_DATE), timestamp)); - } - return null; - } - - @Override - protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Event.CHANGE_DATE), timestamp)); - } - return null; - } - public List getAllActiveUuids() { CriteriaBuilder cb = em.getCriteriaBuilder(); @@ -212,7 +183,7 @@ public List getAllActiveUuids() { } if (RequestContextHolder.isMobileSync()) { - Predicate predicate = limitSynchronizationFilter(cb, from); + Predicate predicate = createLimitedChangeDateFilter(cb, from); if (predicate != null) { filter = CriteriaBuilderHelper.and(cb, filter, predicate); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageService.java index 7fb4b93128a..42ea3887a9c 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageService.java @@ -60,6 +60,16 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public Predicate buildCriteriaFilter(CriteriaBuilder cb, Root labMessage, ExternalMessageCriteria criteria) { Predicate filter = null; if (criteria.getUuid() != null) { 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 a3bb93790f6..5fc8b545524 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 @@ -123,6 +123,16 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public void createMissingFeatureConfigurations() { Map configs = getServerFeatureConfigurations(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/DirectoryImmunizationService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/DirectoryImmunizationService.java index 5f8ca28b615..1a998bb767c 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/DirectoryImmunizationService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/DirectoryImmunizationService.java @@ -72,6 +72,16 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public List getIndexList(ImmunizationCriteria criteria, Integer first, Integer max, List sortProperties) { final CriteriaBuilder cb = em.getCriteriaBuilder(); final CriteriaQuery cq = cb.createQuery(Object[].class); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java index baf23067a33..7e10e8593b0 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java @@ -118,30 +118,6 @@ public void deletePermanent(Immunization immunization) { super.deletePermanent(immunization); } - @Override - protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Immunization.CHANGE_DATE), timestamp)); - } - return null; - } - - @Override - protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Immunization.CHANGE_DATE), timestamp)); - } - return null; - } - public List getEntriesList(Long personId, Disease disease, Integer first, Integer max) { final CriteriaBuilder cb = em.getCriteriaBuilder(); final CriteriaQuery cq = cb.createQuery(Object[].class); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/PopulationDataService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/PopulationDataService.java index 762a3ef2ded..e7aa7783897 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/PopulationDataService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/PopulationDataService.java @@ -59,4 +59,14 @@ public Predicate buildCriteriaFilter(PopulationDataCriteria criteria, CriteriaBu public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { return null; } + + @Override + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/outbreak/OutbreakService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/outbreak/OutbreakService.java index 54ccf0cb78d..43cd390e084 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/outbreak/OutbreakService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/outbreak/OutbreakService.java @@ -57,6 +57,16 @@ public OutbreakService() { super(Outbreak.class); } + @Override + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public List queryByCriteria(OutbreakCriteria criteria, User user, String orderProperty, boolean asc) { CriteriaBuilder cb = em.getCriteriaBuilder(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java index 9e301d6edae..a3dae52a553 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java @@ -192,30 +192,6 @@ private boolean isPermitted(FeatureType featureType, UserRight userRight) { return getCurrentUser().hasUserRight(userRight) && featureConfigurationFacade.isFeatureEnabled(featureType); } - @Override - protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Person.CHANGE_DATE), timestamp)); - } - return null; - } - - @Override - protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Person.CHANGE_DATE), timestamp)); - } - return null; - } - @Override public List getAllUuids() { @@ -333,6 +309,16 @@ public Predicate createUserFilter(PersonQueryContext queryContext, PersonCriteri return userFilter; } + @Override + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + /** * @return {@code null}, if the association is not permitted to query, * otherwise an appropriate {@link Predicate} for the given {@link PersonAssociation}. @@ -593,7 +579,7 @@ private List getAllAfter( } if (RequestContextHolder.isMobileSync()) { - Predicate predicate = limitSynchronizationFilter(cb, personJoin); + Predicate predicate = createLimitedChangeDateFilter(cb, personJoin); if (predicate != null) { filter = CriteriaBuilderHelper.and(cb, filter, predicate); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java index 6b793b63a9a..a8d725a45a5 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java @@ -1,7 +1,5 @@ package de.symeda.sormas.backend.report; -import java.sql.Timestamp; -import java.util.Date; import java.util.List; import javax.ejb.EJB; @@ -15,14 +13,10 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; -import de.symeda.sormas.api.feature.FeatureType; -import de.symeda.sormas.api.feature.FeatureTypeProperty; import de.symeda.sormas.api.report.AggregateReportCriteria; import de.symeda.sormas.api.user.JurisdictionLevel; -import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.backend.common.AdoServiceWithUserFilterAndJurisdiction; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; -import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import de.symeda.sormas.backend.infrastructure.district.District; import de.symeda.sormas.backend.infrastructure.facility.Facility; import de.symeda.sormas.backend.infrastructure.pointofentry.PointOfEntry; @@ -37,13 +31,21 @@ public class AggregateReportService extends AdoServiceWithUserFilterAndJurisdict @EJB private UserService userService; - @EJB - protected FeatureConfigurationFacadeEjb.FeatureConfigurationFacadeEjbLocal featureConfigurationFacade; public AggregateReportService() { super(AggregateReport.class); } + @Override + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public Predicate createCriteriaFilter( AggregateReportCriteria criteria, CriteriaBuilder cb, @@ -187,30 +189,6 @@ public Predicate createUserFilter(AggregateReportQueryContext queryContext) { return filter; } - @Override - protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(AggregateReport.CHANGE_DATE), timestamp)); - } - return null; - } - - @Override - protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(AggregateReport.CHANGE_DATE), timestamp)); - } - return null; - } - public List findBy(AggregateReportCriteria aggregateReportCriteria, User user) { CriteriaBuilder cb = em.getCriteriaBuilder(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportEntryService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportEntryService.java index 723cf3b2f16..d23eaa28184 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportEntryService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportEntryService.java @@ -60,4 +60,14 @@ public long getNumberOfNonZeroEntries(WeeklyReport report) { public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { return weeklyReportService.createUserFilter(cb, cq, from.join(WeeklyReportEntry.WEEKLY_REPORT, JoinType.LEFT)); } + + @Override + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java index 0d35a14ab8f..4df1f400061 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java @@ -17,8 +17,6 @@ *******************************************************************************/ package de.symeda.sormas.backend.report; -import java.sql.Timestamp; -import java.util.Date; import java.util.List; import java.util.Optional; import java.util.stream.Stream; @@ -35,15 +33,11 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; -import de.symeda.sormas.api.feature.FeatureType; -import de.symeda.sormas.api.feature.FeatureTypeProperty; import de.symeda.sormas.api.report.WeeklyReportCriteria; import de.symeda.sormas.api.user.JurisdictionLevel; -import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.api.utils.EpiWeek; import de.symeda.sormas.backend.common.AdoServiceWithUserFilterAndJurisdiction; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; -import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import de.symeda.sormas.backend.infrastructure.district.DistrictService; import de.symeda.sormas.backend.infrastructure.facility.Facility; import de.symeda.sormas.backend.infrastructure.region.Region; @@ -63,13 +57,21 @@ public class WeeklyReportService extends AdoServiceWithUserFilterAndJurisdiction private DistrictService districtService; @EJB private UserService userService; - @EJB - protected FeatureConfigurationFacadeEjb.FeatureConfigurationFacadeEjbLocal featureConfigurationFacade; public WeeklyReportService() { super(WeeklyReport.class); } + @Override + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public long getNumberOfWeeklyReportsByFacility(Facility facility, EpiWeek epiWeek) { CriteriaBuilder cb = em.getCriteriaBuilder(); @@ -121,30 +123,6 @@ public WeeklyReport getByEpiWeekAndUser(EpiWeek epiWeek, User user) { return QueryHelper.getSingleResult(em, cq); } - @Override - protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(WeeklyReport.CHANGE_DATE), timestamp)); - } - return null; - } - - @Override - protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(WeeklyReport.CHANGE_DATE), timestamp)); - } - return null; - } - /** * @see /sormas-backend/doc/UserDataAccess.md */ diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java index 31eac11ca5c..6178b80b965 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java @@ -1,8 +1,6 @@ package de.symeda.sormas.backend.sample; -import java.sql.Timestamp; import java.util.ArrayList; -import java.util.Date; import java.util.List; import javax.ejb.EJB; @@ -22,10 +20,7 @@ import javax.persistence.criteria.Root; import de.symeda.sormas.api.RequestContextHolder; -import de.symeda.sormas.api.feature.FeatureType; -import de.symeda.sormas.api.feature.FeatureTypeProperty; import de.symeda.sormas.api.sample.AdditionalTestCriteria; -import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.api.utils.SortProperty; import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.common.AdoServiceWithUserFilterAndJurisdiction; @@ -33,7 +28,6 @@ import de.symeda.sormas.backend.common.DeletableAdo; import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.event.EventParticipant; -import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import de.symeda.sormas.backend.user.User; import de.symeda.sormas.backend.util.QueryHelper; @@ -43,8 +37,6 @@ public class AdditionalTestService extends AdoServiceWithUserFilterAndJurisdicti @EJB private SampleService sampleService; - @EJB - protected FeatureConfigurationFacadeEjb.FeatureConfigurationFacadeEjbLocal featureConfigurationFacade; public AdditionalTestService() { super(AdditionalTest.class); @@ -64,26 +56,12 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c } @Override - protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(AdditionalTest.CHANGE_DATE), timestamp)); - } + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; } @Override - protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(AdditionalTest.CHANGE_DATE), timestamp)); - } + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { return null; } @@ -174,7 +152,7 @@ public List getAllActiveUuids(User user) { } if (RequestContextHolder.isMobileSync()) { - Predicate predicate = limitSynchronizationFilter(cb, from); + Predicate predicate = createLimitedChangeDateFilter(cb, from); if (predicate != null) { filter = CriteriaBuilderHelper.and(cb, filter, predicate); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java index 512c1c499bf..9d6c938179d 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java @@ -42,11 +42,8 @@ import de.symeda.sormas.api.RequestContextHolder; import de.symeda.sormas.api.common.DeletionDetails; -import de.symeda.sormas.api.feature.FeatureType; -import de.symeda.sormas.api.feature.FeatureTypeProperty; import de.symeda.sormas.api.sample.PathogenTestCriteria; import de.symeda.sormas.api.sample.PathogenTestResultType; -import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.api.utils.SortProperty; import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.common.AbstractDeletableAdoService; @@ -55,7 +52,6 @@ import de.symeda.sormas.backend.common.DeletableAdo; import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.event.EventParticipant; -import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import de.symeda.sormas.backend.user.User; import de.symeda.sormas.backend.util.QueryHelper; @@ -65,8 +61,6 @@ public class PathogenTestService extends AbstractDeletableAdoService from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(PathogenTest.CHANGE_DATE), timestamp)); - } + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; } @Override - protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(PathogenTest.CHANGE_DATE), timestamp)); - } + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { return null; } @@ -123,7 +103,7 @@ public List getAllActiveUuids(User user) { } if (RequestContextHolder.isMobileSync()) { - Predicate predicate = limitSynchronizationFilter(cb, from); + Predicate predicate = createLimitedChangeDateFilter(cb, from); if (predicate != null) { filter = CriteriaBuilderHelper.and(cb, filter, predicate); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java index 05d0b46ccf4..2c707b25c04 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java @@ -52,7 +52,6 @@ import javax.persistence.criteria.Selection; import javax.persistence.criteria.Subquery; -import de.symeda.sormas.api.feature.FeatureTypeProperty; import org.apache.commons.collections.CollectionUtils; import de.symeda.sormas.api.EntityRelevanceStatus; @@ -390,30 +389,6 @@ public List getIndexList(SampleCriteria sampleCriteria, Integer return samples; } - @Override - protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Sample.CHANGE_DATE), timestamp)); - } - return null; - } - - @Override - protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Sample.CHANGE_DATE), timestamp)); - } - return null; - } - public List getEntriesList(SampleCriteria sampleCriteria, Integer first, Integer max) { if (sampleCriteria == null) { return Collections.emptyList(); @@ -502,7 +477,7 @@ public List getAllActiveUuids(User user) { } if (RequestContextHolder.isMobileSync()) { - Predicate predicate = limitSynchronizationFilter(cb, from); + Predicate predicate = createLimitedChangeDateFilter(cb, from); if (predicate != null) { filter = CriteriaBuilderHelper.and(cb, filter, predicate); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/share/ExternalShareInfoService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/share/ExternalShareInfoService.java index d8626a23fbb..1d948a1b506 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/share/ExternalShareInfoService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/share/ExternalShareInfoService.java @@ -66,6 +66,16 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public Predicate buildCriteriaFilter(ExternalShareInfoCriteria criteria, CriteriaBuilder cb, Root shareInfo) { Predicate filter = null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/origin/SormasToSormasOriginInfoService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/origin/SormasToSormasOriginInfoService.java index fa83128d65c..d1545f095cc 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/origin/SormasToSormasOriginInfoService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/origin/SormasToSormasOriginInfoService.java @@ -45,6 +45,16 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public SormasToSormasOriginInfo getByPerson(String personUuid) { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cq = cb.createQuery(SormasToSormasOriginInfo.class); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/incoming/SormasToSormasShareRequestService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/incoming/SormasToSormasShareRequestService.java index ebc7c052d48..cbb6d4448c2 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/incoming/SormasToSormasShareRequestService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/incoming/SormasToSormasShareRequestService.java @@ -58,6 +58,16 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public Predicate buildCriteriaFilter(ShareRequestCriteria criteria, CriteriaBuilder cb, Root root) { Predicate filter = null; if (criteria.getStatus() != null) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/ShareRequestInfoService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/ShareRequestInfoService.java index 1c43b66afd1..f1971fd3eeb 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/ShareRequestInfoService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/ShareRequestInfoService.java @@ -49,6 +49,16 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public Predicate buildCriteriaFilter(ShareRequestCriteria criteria, CriteriaBuilder cb, Root root) { Predicate filter = null; if (criteria.getStatus() != null) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfoService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfoService.java index 8833177d72a..824c4de1012 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfoService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfoService.java @@ -71,6 +71,16 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public Predicate buildCriteriaFilter(SormasToSormasShareInfoCriteria criteria, CriteriaBuilder cb, Root from) { Predicate filter = null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java index e931553f4e2..91f073382ef 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java @@ -42,7 +42,6 @@ import javax.persistence.criteria.Root; import javax.persistence.criteria.Selection; -import de.symeda.sormas.api.utils.DateHelper; import org.apache.commons.lang3.ArrayUtils; import de.symeda.sormas.api.EntityRelevanceStatus; @@ -122,30 +121,6 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c return filter; } - @Override - protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Task.CHANGE_DATE), timestamp)); - } - return null; - } - - @Override - protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Task.CHANGE_DATE), timestamp)); - } - return null; - } - public List getAllActiveUuids(User user) { final CriteriaBuilder cb = em.getCriteriaBuilder(); @@ -161,7 +136,7 @@ public List getAllActiveUuids(User user) { } if (RequestContextHolder.isMobileSync()) { - Predicate predicate = limitSynchronizationFilter(cb, from); + Predicate predicate = createLimitedChangeDateFilter(cb, from); if (predicate != null) { filter = CriteriaBuilderHelper.and(cb, filter, predicate); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java index 5131b77df92..8929351ef0d 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java @@ -1,7 +1,5 @@ package de.symeda.sormas.backend.therapy; -import java.sql.Timestamp; -import java.util.Date; import java.util.List; import javax.ejb.EJB; @@ -16,10 +14,6 @@ import javax.persistence.criteria.Root; import de.symeda.sormas.api.RequestContextHolder; -import de.symeda.sormas.api.feature.FeatureType; -import de.symeda.sormas.api.feature.FeatureTypeProperty; -import de.symeda.sormas.api.utils.DateHelper; -import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import org.apache.commons.lang3.StringUtils; import de.symeda.sormas.api.therapy.PrescriptionCriteria; @@ -38,8 +32,6 @@ public class PrescriptionService extends AdoServiceWithUserFilterAndJurisdiction @EJB private CaseService caseService; - @EJB - protected FeatureConfigurationFacadeEjb.FeatureConfigurationFacadeEjbLocal featureConfigurationFacade; public PrescriptionService() { super(Prescription.class); @@ -79,27 +71,14 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c } @Override - protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Prescription.CHANGE_DATE), timestamp)); - } + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; } @Override - protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Prescription.CHANGE_DATE), timestamp)); - } + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { return null; + } public List getAllActiveUuids(User user) { @@ -118,7 +97,7 @@ public List getAllActiveUuids(User user) { } if (RequestContextHolder.isMobileSync()) { - Predicate predicate = limitSynchronizationFilter(cb, from); + Predicate predicate = createLimitedChangeDateFilter(cb, from); if (predicate != null) { filter = CriteriaBuilderHelper.and(cb, filter, predicate); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java index 8f4e1b3bd60..80c615ec469 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java @@ -1,7 +1,5 @@ package de.symeda.sormas.backend.therapy; -import java.sql.Timestamp; -import java.util.Date; import java.util.List; import javax.ejb.EJB; @@ -17,10 +15,6 @@ import javax.persistence.criteria.Root; import de.symeda.sormas.api.RequestContextHolder; -import de.symeda.sormas.api.feature.FeatureType; -import de.symeda.sormas.api.feature.FeatureTypeProperty; -import de.symeda.sormas.api.utils.DateHelper; -import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import org.apache.commons.lang3.StringUtils; import de.symeda.sormas.api.therapy.TreatmentCriteria; @@ -39,8 +33,6 @@ public class TreatmentService extends AdoServiceWithUserFilterAndJurisdiction from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Treatment.CHANGE_DATE), timestamp)); - } + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; } @Override - protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Treatment.CHANGE_DATE), timestamp)); - } + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { return null; } @@ -118,7 +96,7 @@ public List getAllActiveUuids(User user) { } if (RequestContextHolder.isMobileSync()) { - Predicate predicate = limitSynchronizationFilter(cb, from); + Predicate predicate = createLimitedChangeDateFilter(cb, from); if (predicate != null) { filter = CriteriaBuilderHelper.and(cb, filter, predicate); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/BaseTravelEntryService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/BaseTravelEntryService.java index 031c70940ee..15de0bd4402 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/BaseTravelEntryService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/BaseTravelEntryService.java @@ -30,6 +30,16 @@ public Predicate inJurisdictionOrOwned(CriteriaBuilder cb, CriteriaQuery quer return inJurisdictionOrOwned(new TravelEntryQueryContext(cb, query, from)); } + @Override + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public Predicate inJurisdictionOrOwned(TravelEntryQueryContext qc) { return inJurisdictionOrOwned(qc, userService.getCurrentUser()); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/TravelEntryService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/TravelEntryService.java index 5152d47fff5..e181cc96dbe 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/TravelEntryService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/TravelEntryService.java @@ -58,7 +58,6 @@ public class TravelEntryService extends BaseTravelEntryService { @EJB private DocumentService documentService; - public List getByPersonUuids(List personUuids) { List travelEntries = new LinkedList<>(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserRoleService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserRoleService.java index 90af64c2f5d..2291e582acc 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserRoleService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserRoleService.java @@ -66,6 +66,16 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public UserRole getByCaption(String caption) { CriteriaBuilder cb = em.getCriteriaBuilder(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserService.java index b04333e6a35..5149ea2094f 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserService.java @@ -100,6 +100,16 @@ public UserService() { super(User.class); } + @Override + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public User createUser() { User user = new User(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/vaccination/VaccinationService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/vaccination/VaccinationService.java index 8b053413f0f..87a8c705595 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/vaccination/VaccinationService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/vaccination/VaccinationService.java @@ -79,6 +79,16 @@ public VaccinationService() { super(Vaccination.class); } + @Override + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { + return null; + } + + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { + return null; + } + public Map getLastVaccinationType() { Map result = new HashMap<>(); String queryString = diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java index 9128730d95d..63208ba62d1 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java @@ -43,8 +43,6 @@ import de.symeda.sormas.api.RequestContextHolder; import de.symeda.sormas.api.caze.CaseLogic; import de.symeda.sormas.api.contact.ContactLogic; -import de.symeda.sormas.api.feature.FeatureType; -import de.symeda.sormas.api.feature.FeatureTypeProperty; import de.symeda.sormas.api.followup.FollowUpLogic; import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.api.visit.VisitCriteria; @@ -60,7 +58,6 @@ import de.symeda.sormas.backend.contact.ContactJoins; import de.symeda.sormas.backend.contact.ContactQueryContext; import de.symeda.sormas.backend.contact.ContactService; -import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import de.symeda.sormas.backend.person.Person; import de.symeda.sormas.backend.symptoms.Symptoms; import de.symeda.sormas.backend.user.User; @@ -76,9 +73,6 @@ public class VisitService extends AdoServiceWithUserFilterAndJurisdiction @EJB private CaseService caseService; - @EJB - protected FeatureConfigurationFacadeEjb.FeatureConfigurationFacadeEjbLocal featureConfigurationFacade; - public VisitService() { super(Visit.class); } @@ -93,31 +87,19 @@ public boolean inJurisdictionOrOwned(Visit entity) { return fulfillsCondition(entity, (cb, cq, from) -> inJurisdictionOrOwned(cb, cq, from)); } - @SuppressWarnings("rawtypes") - private Predicate inJurisdictionOrOwned(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return inJurisdictionOrOwned(new VisitQueryContext(cb, cq, from)); + @Override + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { + return null; } - protected Predicate limitSynchronizationFilter(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(Visit.CHANGE_DATE), timestamp)); - } + @Override + protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { return null; } - protected Predicate limitSynchronizationFilterObsoleteEntities(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Timestamp timestamp = Timestamp.from(DateHelper.subtractDays(new Date(), maxChangeDatePeriod).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(Visit.CHANGE_DATE), timestamp)); - } - return null; + @SuppressWarnings("rawtypes") + private Predicate inJurisdictionOrOwned(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return inJurisdictionOrOwned(new VisitQueryContext(cb, cq, from)); } public Predicate inJurisdictionOrOwned(VisitQueryContext queryContext) { @@ -203,7 +185,7 @@ public List getAllAfter(Date since, Integer batchSize, String lastSynchro filter = CriteriaBuilderHelper.and(cb, filter, createChangeDateFilter(cb, from, since, lastSynchronizedUuid)); } if (RequestContextHolder.isMobileSync()) { - Predicate predicate = limitSynchronizationFilter(cb, from); + Predicate predicate = createLimitedChangeDateFilter(cb, from); if (predicate != null) { filter = CriteriaBuilderHelper.and(cb, filter, predicate); } diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbUserFilterTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbUserFilterTest.java index 57f18552fb5..84c1410197c 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbUserFilterTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbUserFilterTest.java @@ -148,27 +148,15 @@ public void testGetCasesWithExcludeNoCaseClassifiedAndMaxChangedDate() { FeatureConfigurationIndexDto featureConfiguration = new FeatureConfigurationIndexDto(DataHelper.createUuid(), null, null, null, null, null, true, null); getFeatureConfigurationFacade().saveFeatureConfiguration(featureConfiguration, FeatureType.LIMITED_SYNCHRONIZATION); - FeatureConfigurationIndexDto featureConfigurationMaxChangeDate = - new FeatureConfigurationIndexDto(DataHelper.createUuid(), null, null, null, null, null, true, null); - getFeatureConfigurationFacade().saveFeatureConfiguration(featureConfigurationMaxChangeDate, FeatureType.LIMITED_SYNCHRONIZATION); SessionImpl em = (SessionImpl) getEntityManager(); QueryImplementor query = em.createQuery("select f from featureconfiguration f"); - List results = (List) query.getResultList(); - HashMap excludeNoCaseClassifiedProperties = new HashMap<>(); - excludeNoCaseClassifiedProperties.put(FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES, true); - HashMap maxChangeDateProperties = new HashMap<>(); - int maxChangeDateOffset = 30; - maxChangeDateProperties.put(FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, maxChangeDateOffset); - - results.forEach(fc -> { - if (fc.getFeatureType().equals(FeatureType.LIMITED_SYNCHRONIZATION)) { - fc.setProperties(excludeNoCaseClassifiedProperties); - } else { - fc.setProperties(maxChangeDateProperties); - } - em.save(fc); - }); + FeatureConfiguration singleResult = (FeatureConfiguration) query.getSingleResult(); + HashMap properties = new HashMap<>(); + properties.put(FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES, true); + properties.put(FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, 30); + singleResult.setProperties(properties); + em.save(singleResult); MockProducer.setMobileSync(true); From 93c4587f4cc224509c112a799827591c3653ae68 Mon Sep 17 00:00:00 2001 From: dinua Date: Thu, 8 Dec 2022 15:32:49 +0200 Subject: [PATCH 006/166] #9360 activate poe tab --- .../de/symeda/sormas/api/caze/CaseFacade.java | 2 ++ .../sormas/backend/caze/CaseFacadeEjb.java | 17 +++++++++++++++ .../backend/caze/CaseFacadeEjbTest.java | 21 +++++++++++++++++++ .../sormas/ui/caze/AbstractCaseView.java | 10 ++++++++- 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseFacade.java index b4fd9cddd0a..eb0a07a4b63 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseFacade.java @@ -230,4 +230,6 @@ void saveBulkEditWithFacilities( Pair getRegionAndDistrictRefsOf(CaseReferenceDto caze); + boolean hasPointOfEntry(String caseUuid); + } 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 21945a42be5..3dced084a6c 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 @@ -4198,6 +4198,23 @@ public void updateSymptomsByVisit(Visit visit) { caseSave(cazeDto, true, visit.getCaze(), cazeDto, true, true); } + @RightsAllowed({ + UserRight._PORT_HEALTH_INFO_VIEW }) + public boolean hasPointOfEntry(String caseUuid) { + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(Long.class); + Root caseRoot = cq.from(Case.class); + + CaseJoins caseCaseJoins = new CaseJoins(caseRoot); + Join pointOfEntryJoin = caseCaseJoins.getPointOfEntry(); + + cq.select(cb.count(caseRoot)); + cq.where(cb.and(cb.equal(caseRoot.get(Case.UUID), caseUuid), cb.isNotNull(pointOfEntryJoin.get(PointOfEntry.ID)))); + + long count = em.createQuery(cq).getSingleResult(); + return count > 0; + } + @LocalBean @Stateless public static class CaseFacadeEjbLocal extends CaseFacadeEjb { diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbTest.java index 3bf46f0696a..bcfe0ba598c 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbTest.java @@ -3116,6 +3116,27 @@ public void testGetCaseSelectionListWithArchivedCases() { assertTrue(caseUuids.contains(case2.getUuid())); } + @Test + public void testHasPointOfEntry() { + RDCF rdcf = creator.createRDCF(); + UserDto user = creator.createUser(rdcf, creator.getUserRoleReference(DefaultUserRole.NATIONAL_USER)); + PersonDto personDto = creator.createPerson("John", "Doe"); + + CaseDataDto case1 = creator.createCase(user.toReference(), personDto.toReference(), rdcf); + CaseDataDto case2 = creator.createCase(user.toReference(), rdcf, c -> { + c.setPerson(personDto.toReference()); + c.setPointOfEntry(rdcf.pointOfEntry); + }); + + case1.setPointOfEntry(null); + getCaseFacade().save(case1); + + boolean hasPointOfEntry = getCaseFacade().hasPointOfEntry(case1.getUuid()); + assertFalse(hasPointOfEntry); + hasPointOfEntry = getCaseFacade().hasPointOfEntry(case2.getUuid()); + assertTrue(hasPointOfEntry); + } + private static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz "; private static final SecureRandom rnd = new SecureRandom(); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/AbstractCaseView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/AbstractCaseView.java index e1079923663..e25aca179ec 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/AbstractCaseView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/AbstractCaseView.java @@ -174,7 +174,7 @@ public void refreshMenu(SubMenu menu, String params) { params); } if (caze.getCaseOrigin() == CaseOrigin.POINT_OF_ENTRY - && caze.getPointOfEntry() != null + && hasPointOfEntry(caze) && UserProvider.getCurrent().hasUserRight(UserRight.PORT_HEALTH_INFO_VIEW)) { menu.addView( PortHealthInfoView.VIEW_NAME, @@ -231,6 +231,14 @@ public void refreshMenu(SubMenu menu, String params) { ExternalJournalUtil.getExternalJournalUiButton(casePerson, caze).ifPresent(getButtonsLayout()::addComponent); } } + + private boolean hasPointOfEntry(CaseDataDto caze) { + if (caze.getPointOfEntry() != null) { + boolean hasPoe = FacadeProvider.getCaseFacade().hasPointOfEntry(caze.getUuid()); + return hasPoe; + } + return true; + } @Override public void enter(ViewChangeEvent event) { From 9dbb09dd4e7abbc10a4616ca0aeff22f759ad267 Mon Sep 17 00:00:00 2001 From: dinua Date: Fri, 9 Dec 2022 12:55:08 +0200 Subject: [PATCH 007/166] #9360 find if case has poe --- .../de/symeda/sormas/api/caze/CaseFacade.java | 2 -- .../pointofentry/PointOfEntryFacade.java | 2 ++ .../sormas/backend/caze/CaseFacadeEjb.java | 17 ---------- .../pointofentry/PointOfEntryFacadeEjb.java | 21 ++++++++++++ .../backend/caze/CaseFacadeEjbTest.java | 21 ------------ .../PointOfEntryFacadeEjbTest.java | 33 ++++++++++++++++++- .../sormas/ui/caze/AbstractCaseView.java | 10 +----- .../symeda/sormas/ui/caze/CaseController.java | 13 +++++--- 8 files changed, 65 insertions(+), 54 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseFacade.java index eb0a07a4b63..b4fd9cddd0a 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseFacade.java @@ -230,6 +230,4 @@ void saveBulkEditWithFacilities( Pair getRegionAndDistrictRefsOf(CaseReferenceDto caze); - boolean hasPointOfEntry(String caseUuid); - } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/infrastructure/pointofentry/PointOfEntryFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/infrastructure/pointofentry/PointOfEntryFacade.java index 667a8d2cf04..dff2d64ce9d 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/infrastructure/pointofentry/PointOfEntryFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/infrastructure/pointofentry/PointOfEntryFacade.java @@ -25,4 +25,6 @@ public interface PointOfEntryFacade extends InfrastructureFacade getIndexPage(PointOfEntryCriteria criteria, Integer offset, Integer size, List sortProperties); boolean hasArchivedParentInfrastructure(Collection pointOfEntryUuids); + + PointOfEntryDto getByCaseUuid(String caseUuid); } 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 3dced084a6c..21945a42be5 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 @@ -4198,23 +4198,6 @@ public void updateSymptomsByVisit(Visit visit) { caseSave(cazeDto, true, visit.getCaze(), cazeDto, true, true); } - @RightsAllowed({ - UserRight._PORT_HEALTH_INFO_VIEW }) - public boolean hasPointOfEntry(String caseUuid) { - CriteriaBuilder cb = em.getCriteriaBuilder(); - CriteriaQuery cq = cb.createQuery(Long.class); - Root caseRoot = cq.from(Case.class); - - CaseJoins caseCaseJoins = new CaseJoins(caseRoot); - Join pointOfEntryJoin = caseCaseJoins.getPointOfEntry(); - - cq.select(cb.count(caseRoot)); - cq.where(cb.and(cb.equal(caseRoot.get(Case.UUID), caseUuid), cb.isNotNull(pointOfEntryJoin.get(PointOfEntry.ID)))); - - long count = em.createQuery(cq).getSingleResult(); - return count > 0; - } - @LocalBean @Stateless public static class CaseFacadeEjbLocal extends CaseFacadeEjb { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryFacadeEjb.java index f70c7d23531..189807a075a 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryFacadeEjb.java @@ -1,5 +1,8 @@ package de.symeda.sormas.backend.infrastructure.pointofentry; +import com.vladmihalcea.hibernate.query.SQLExtractor; +import de.symeda.sormas.backend.caze.Case; +import de.symeda.sormas.backend.caze.CaseJoins; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -10,6 +13,7 @@ import javax.ejb.LocalBean; import javax.ejb.Stateless; import javax.inject.Inject; +import javax.persistence.Query; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Expression; @@ -221,6 +225,23 @@ public List getIndexList(PointOfEntryCriteria criteria, Integer return QueryHelper.getResultList(em, cq, first, max, this::toDto); } + @Override + public PointOfEntryDto getByCaseUuid(String caseUuid){ + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(PointOfEntry.class); + Root root = cq.from(Case.class); + CaseJoins caseCaseJoins = new CaseJoins(root); + Join pointOfEntryJoin = caseCaseJoins.getPointOfEntry(); + + cq.select(pointOfEntryJoin); + cq.where(cb.equal(root.get(Case.UUID), caseUuid)); + + Query query = em.createQuery(cq); + String sql = SQLExtractor.from(query); + + return QueryHelper.getSingleResult(em,cq, this::toDto); + } + @Override public boolean hasArchivedParentInfrastructure(Collection pointOfEntryUuids) { diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbTest.java index bcfe0ba598c..3bf46f0696a 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbTest.java @@ -3116,27 +3116,6 @@ public void testGetCaseSelectionListWithArchivedCases() { assertTrue(caseUuids.contains(case2.getUuid())); } - @Test - public void testHasPointOfEntry() { - RDCF rdcf = creator.createRDCF(); - UserDto user = creator.createUser(rdcf, creator.getUserRoleReference(DefaultUserRole.NATIONAL_USER)); - PersonDto personDto = creator.createPerson("John", "Doe"); - - CaseDataDto case1 = creator.createCase(user.toReference(), personDto.toReference(), rdcf); - CaseDataDto case2 = creator.createCase(user.toReference(), rdcf, c -> { - c.setPerson(personDto.toReference()); - c.setPointOfEntry(rdcf.pointOfEntry); - }); - - case1.setPointOfEntry(null); - getCaseFacade().save(case1); - - boolean hasPointOfEntry = getCaseFacade().hasPointOfEntry(case1.getUuid()); - assertFalse(hasPointOfEntry); - hasPointOfEntry = getCaseFacade().hasPointOfEntry(case2.getUuid()); - assertTrue(hasPointOfEntry); - } - private static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz "; private static final SecureRandom rnd = new SecureRandom(); diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PointOfEntryFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PointOfEntryFacadeEjbTest.java index 91ccc320a67..a8f5e41883a 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PointOfEntryFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PointOfEntryFacadeEjbTest.java @@ -1,7 +1,16 @@ package de.symeda.sormas.backend.infrastructure; import static org.junit.jupiter.api.Assertions.assertEquals; - +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import de.symeda.sormas.api.caze.CaseDataDto; +import de.symeda.sormas.api.person.PersonDto; +import de.symeda.sormas.api.user.DefaultUserRole; +import de.symeda.sormas.api.user.UserDto; +import de.symeda.sormas.backend.TestDataCreator.RDCF; import java.util.Date; import java.util.List; @@ -64,4 +73,26 @@ void testCount() { assertEquals(1, pointOfEntryFacade.count(new PointOfEntryCriteria().nameLike("poe1"))); } + @Test + public void testGetPointOfEntryByCaseUuid() { + RDCF rdcf = creator.createRDCF(); + UserDto user = creator.createUser(rdcf, creator.getUserRoleReference(DefaultUserRole.NATIONAL_USER)); + PersonDto personDto = creator.createPerson("John", "Doe"); + + CaseDataDto case1 = creator.createCase(user.toReference(), personDto.toReference(), rdcf); + CaseDataDto case2 = creator.createCase(user.toReference(), rdcf, c -> { + c.setPerson(personDto.toReference()); + c.setPointOfEntry(rdcf.pointOfEntry); + }); + + case1.setPointOfEntry(null); + getCaseFacade().save(case1); + + PointOfEntryDto pointOfEntryDto = getPointOfEntryFacade().getByCaseUuid(case1.getUuid()); + assertNull(pointOfEntryDto); + pointOfEntryDto = getPointOfEntryFacade().getByCaseUuid(case2.getUuid()); + assertNotNull(pointOfEntryDto); + assertEquals(rdcf.pointOfEntry.getUuid(), pointOfEntryDto.getUuid()); + } + } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/AbstractCaseView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/AbstractCaseView.java index e25aca179ec..5bae83cc6b2 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/AbstractCaseView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/AbstractCaseView.java @@ -174,7 +174,7 @@ public void refreshMenu(SubMenu menu, String params) { params); } if (caze.getCaseOrigin() == CaseOrigin.POINT_OF_ENTRY - && hasPointOfEntry(caze) + && ControllerProvider.getCaseController().hasPointOfEntry(caze) && UserProvider.getCurrent().hasUserRight(UserRight.PORT_HEALTH_INFO_VIEW)) { menu.addView( PortHealthInfoView.VIEW_NAME, @@ -231,14 +231,6 @@ && hasPointOfEntry(caze) ExternalJournalUtil.getExternalJournalUiButton(casePerson, caze).ifPresent(getButtonsLayout()::addComponent); } } - - private boolean hasPointOfEntry(CaseDataDto caze) { - if (caze.getPointOfEntry() != null) { - boolean hasPoe = FacadeProvider.getCaseFacade().hasPointOfEntry(caze.getUuid()); - return hasPoe; - } - return true; - } @Override public void enter(ViewChangeEvent event) { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java index 379c7bb2674..100df0b2e08 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java @@ -91,7 +91,6 @@ import de.symeda.sormas.api.infrastructure.facility.FacilityReferenceDto; import de.symeda.sormas.api.infrastructure.facility.FacilityType; import de.symeda.sormas.api.infrastructure.pointofentry.PointOfEntryDto; -import de.symeda.sormas.api.infrastructure.pointofentry.PointOfEntryReferenceDto; import de.symeda.sormas.api.infrastructure.region.RegionReferenceDto; import de.symeda.sormas.api.messaging.MessageType; import de.symeda.sormas.api.person.PersonDto; @@ -1341,13 +1340,12 @@ public CommitDiscardWrapperComponent getMaternalHistoryComp public CommitDiscardWrapperComponent getPortHealthInfoComponent(final String caseUuid) { CaseDataDto caze = findCase(caseUuid); - PointOfEntryReferenceDto casePointOfEntry = caze.getPointOfEntry(); - if (casePointOfEntry == null) { + if (!hasPointOfEntry(caze)) { return null; } - PointOfEntryDto pointOfEntry = FacadeProvider.getPointOfEntryFacade().getByUuid(casePointOfEntry.getUuid()); + PointOfEntryDto pointOfEntry = FacadeProvider.getPointOfEntryFacade().getByCaseUuid(caseUuid);// getByUuid(casePointOfEntry.getUuid()); PortHealthInfoForm form = new PortHealthInfoForm(pointOfEntry, caze.getPointOfEntryDetails()); form.setValue(caze.getPortHealthInfo()); @@ -1848,4 +1846,11 @@ private static class JurisdictionValues { protected String facilityDetails; } + public boolean hasPointOfEntry(CaseDataDto caze) { + if (caze.getPointOfEntry() != null) { + PointOfEntryDto pointOfEntryDto = FacadeProvider.getPointOfEntryFacade().getByCaseUuid(caze.getUuid()); + return pointOfEntryDto != null; + } + return true; + } } From a5969e57ba519ecdc918af0c8e2a63266cbffc3e Mon Sep 17 00:00:00 2001 From: dinua Date: Mon, 12 Dec 2022 11:03:52 +0200 Subject: [PATCH 008/166] #9360 show port health tab --- .../de/symeda/sormas/api/FacadeProvider.java | 5 +++ .../porthealthinfo/PortHealthInfoFacade.java | 1 + .../PortHealthInfoFacadeEjb.java | 27 ++++++++++++- .../pointofentry/PointOfEntryFacadeEjb.java | 13 ++----- .../sormas/backend/AbstractBeanTest.java | 6 +++ .../PortHealthInfoFacadeEjbTest.java | 39 +++++++++++++++++++ .../symeda/sormas/ui/caze/CaseController.java | 13 ++++++- 7 files changed, 92 insertions(+), 12 deletions(-) create mode 100644 sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PortHealthInfoFacadeEjbTest.java diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/FacadeProvider.java b/sormas-api/src/main/java/de/symeda/sormas/api/FacadeProvider.java index 16383b20a47..e308e785424 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/FacadeProvider.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/FacadeProvider.java @@ -14,6 +14,7 @@ */ package de.symeda.sormas.api; +import de.symeda.sormas.api.caze.porthealthinfo.PortHealthInfoFacade; import javax.naming.ConfigurationException; import javax.naming.InitialContext; import javax.naming.NamingException; @@ -318,6 +319,10 @@ public static PointOfEntryFacade getPointOfEntryFacade() { return get().lookupEjbRemote(PointOfEntryFacade.class); } + public static PortHealthInfoFacade getPortHealthInfoFacade() { + return get().lookupEjbRemote(PortHealthInfoFacade.class); + } + public static PopulationDataFacade getPopulationDataFacade() { return get().lookupEjbRemote(PopulationDataFacade.class); } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/caze/porthealthinfo/PortHealthInfoFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/caze/porthealthinfo/PortHealthInfoFacade.java index 3dffe895668..cd8a9e1610f 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/caze/porthealthinfo/PortHealthInfoFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/caze/porthealthinfo/PortHealthInfoFacade.java @@ -5,4 +5,5 @@ @Remote public interface PortHealthInfoFacade { + PortHealthInfoDto getByCaseUuid(String caseUuid); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoFacadeEjb.java index dae0f5825aa..f960098c267 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoFacadeEjb.java @@ -1,13 +1,22 @@ package de.symeda.sormas.backend.caze.porthealthinfo; -import javax.ejb.EJB; import javax.ejb.LocalBean; import javax.ejb.Stateless; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Join; +import javax.persistence.criteria.JoinType; +import javax.persistence.criteria.Root; import javax.validation.constraints.NotNull; import de.symeda.sormas.api.caze.porthealthinfo.PortHealthInfoDto; import de.symeda.sormas.api.caze.porthealthinfo.PortHealthInfoFacade; +import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.util.DtoHelper; +import de.symeda.sormas.backend.util.ModelConstants; +import de.symeda.sormas.backend.util.QueryHelper; @Stateless(name = "PortHealthInfoFacade") public class PortHealthInfoFacadeEjb implements PortHealthInfoFacade { @@ -75,6 +84,22 @@ public PortHealthInfo fillOrBuildEntity(@NotNull PortHealthInfoDto source, PortH return target; } + @PersistenceContext(unitName = ModelConstants.PERSISTENCE_UNIT_NAME) + protected EntityManager em; + + @Override + public PortHealthInfoDto getByCaseUuid(String caseUuid) { + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(PortHealthInfo.class); + Root root = cq.from(Case.class); + Join portHealthJoin = root.join(Case.PORT_HEALTH_INFO, JoinType.LEFT); + + cq.select(portHealthJoin); + cq.where(cb.equal(root.get(Case.UUID), caseUuid)); + + return QueryHelper.getSingleResult(em, cq, PortHealthInfoFacadeEjb::toDto); + } + @LocalBean @Stateless public static class PortHealthInfoFacadeEjbLocal extends PortHealthInfoFacadeEjb { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryFacadeEjb.java index 189807a075a..482c7e9584e 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryFacadeEjb.java @@ -1,8 +1,5 @@ package de.symeda.sormas.backend.infrastructure.pointofentry; -import com.vladmihalcea.hibernate.query.SQLExtractor; -import de.symeda.sormas.backend.caze.Case; -import de.symeda.sormas.backend.caze.CaseJoins; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -13,7 +10,6 @@ import javax.ejb.LocalBean; import javax.ejb.Stateless; import javax.inject.Inject; -import javax.persistence.Query; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Expression; @@ -40,6 +36,8 @@ import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.api.utils.SortProperty; import de.symeda.sormas.api.utils.ValidationRuntimeException; +import de.symeda.sormas.backend.caze.Case; +import de.symeda.sormas.backend.caze.CaseJoins; import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb.FeatureConfigurationFacadeEjbLocal; import de.symeda.sormas.backend.infrastructure.AbstractInfrastructureFacadeEjb; import de.symeda.sormas.backend.infrastructure.district.District; @@ -226,7 +224,7 @@ public List getIndexList(PointOfEntryCriteria criteria, Integer } @Override - public PointOfEntryDto getByCaseUuid(String caseUuid){ + public PointOfEntryDto getByCaseUuid(String caseUuid) { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cq = cb.createQuery(PointOfEntry.class); Root root = cq.from(Case.class); @@ -236,10 +234,7 @@ public PointOfEntryDto getByCaseUuid(String caseUuid){ cq.select(pointOfEntryJoin); cq.where(cb.equal(root.get(Case.UUID), caseUuid)); - Query query = em.createQuery(cq); - String sql = SQLExtractor.from(query); - - return QueryHelper.getSingleResult(em,cq, this::toDto); + return QueryHelper.getSingleResult(em, cq, this::toDto); } @Override diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/AbstractBeanTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/AbstractBeanTest.java index 665aada5a71..3fe45d4c390 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/AbstractBeanTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/AbstractBeanTest.java @@ -19,6 +19,8 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; +import de.symeda.sormas.api.caze.porthealthinfo.PortHealthInfoFacade; +import de.symeda.sormas.backend.caze.porthealthinfo.PortHealthInfoFacadeEjb.PortHealthInfoFacadeEjbLocal; import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.List; @@ -532,6 +534,10 @@ public PointOfEntryFacade getPointOfEntryFacade() { return getBean(PointOfEntryFacadeEjbLocal.class); } + public PortHealthInfoFacade getPortHealthInfoFacade() { + return getBean(PortHealthInfoFacadeEjbLocal.class); + } + public FacilityFacade getFacilityFacade() { return getBean(FacilityFacadeEjbLocal.class); } diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PortHealthInfoFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PortHealthInfoFacadeEjbTest.java new file mode 100644 index 00000000000..d6760d5b057 --- /dev/null +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PortHealthInfoFacadeEjbTest.java @@ -0,0 +1,39 @@ +package de.symeda.sormas.backend.infrastructure; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.Test; + +import de.symeda.sormas.api.caze.CaseDataDto; +import de.symeda.sormas.api.caze.porthealthinfo.PortHealthInfoDto; +import de.symeda.sormas.api.person.PersonDto; +import de.symeda.sormas.api.user.DefaultUserRole; +import de.symeda.sormas.api.user.UserDto; +import de.symeda.sormas.backend.AbstractBeanTest; +import de.symeda.sormas.backend.TestDataCreator.RDCF; + +class PortHealthInfoFacadeEjbTest extends AbstractBeanTest { + + @Test + public void testGetPortHealthInfoByCaseUuid() { + RDCF rdcf = creator.createRDCF(); + UserDto user = creator.createUser(rdcf, creator.getUserRoleReference(DefaultUserRole.NATIONAL_USER)); + PersonDto personDto = creator.createPerson("John", "Doe"); + + PortHealthInfoDto portHealthInfoDto = PortHealthInfoDto.build(); + portHealthInfoDto.setAirlineName("WorldAir"); + + CaseDataDto caseDataDto = creator.createCase(user.toReference(), rdcf, c -> { + c.setPerson(personDto.toReference()); + c.setPointOfEntry(rdcf.pointOfEntry); + c.setPortHealthInfo(portHealthInfoDto); + }); + + PortHealthInfoDto healthInfoDto = getPortHealthInfoFacade().getByCaseUuid(caseDataDto.getUuid()); + assertNotNull(healthInfoDto); + assertEquals(portHealthInfoDto.getUuid(), healthInfoDto.getUuid()); + assertEquals(portHealthInfoDto.getAirlineName(), healthInfoDto.getAirlineName()); + } + +} diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java index 100df0b2e08..4c8715f5ad7 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java @@ -15,6 +15,7 @@ package de.symeda.sormas.ui.caze; +import de.symeda.sormas.api.caze.porthealthinfo.PortHealthInfoDto; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -1347,7 +1348,7 @@ public CommitDiscardWrapperComponent getPortHealthInfoCompon PointOfEntryDto pointOfEntry = FacadeProvider.getPointOfEntryFacade().getByCaseUuid(caseUuid);// getByUuid(casePointOfEntry.getUuid()); PortHealthInfoForm form = new PortHealthInfoForm(pointOfEntry, caze.getPointOfEntryDetails()); - form.setValue(caze.getPortHealthInfo()); + form.setValue(getPortHealthInfo(caze)); final CommitDiscardWrapperComponent component = new CommitDiscardWrapperComponent( form, @@ -1847,10 +1848,18 @@ private static class JurisdictionValues { } public boolean hasPointOfEntry(CaseDataDto caze) { - if (caze.getPointOfEntry() != null) { + if (caze.getPointOfEntry() == null) { PointOfEntryDto pointOfEntryDto = FacadeProvider.getPointOfEntryFacade().getByCaseUuid(caze.getUuid()); return pointOfEntryDto != null; } return true; } + + public PortHealthInfoDto getPortHealthInfo(CaseDataDto caze) { + PortHealthInfoDto portHealthInfoDto = caze.getPortHealthInfo(); + if (portHealthInfoDto == null) { + portHealthInfoDto = FacadeProvider.getPortHealthInfoFacade().getByCaseUuid(caze.getUuid()); + } + return portHealthInfoDto; + } } From 479beef03e0c6bdd90df9d26c50361addbbc820f Mon Sep 17 00:00:00 2001 From: dinua Date: Mon, 12 Dec 2022 11:31:14 +0200 Subject: [PATCH 009/166] #9369 refactor code --- .../java/de/symeda/sormas/api/FacadeProvider.java | 2 +- .../caze/porthealthinfo/PortHealthInfoFacade.java | 2 +- .../porthealthinfo/PortHealthInfoFacadeEjb.java | 6 +++--- .../de/symeda/sormas/backend/AbstractBeanTest.java | 14 +++++++------- .../infrastructure/PointOfEntryFacadeEjbTest.java | 12 +++++------- .../PortHealthInfoFacadeEjbTest.java | 1 - .../de/symeda/sormas/ui/caze/CaseController.java | 2 +- 7 files changed, 18 insertions(+), 21 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/FacadeProvider.java b/sormas-api/src/main/java/de/symeda/sormas/api/FacadeProvider.java index e308e785424..14aae438c95 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/FacadeProvider.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/FacadeProvider.java @@ -14,7 +14,6 @@ */ package de.symeda.sormas.api; -import de.symeda.sormas.api.caze.porthealthinfo.PortHealthInfoFacade; import javax.naming.ConfigurationException; import javax.naming.InitialContext; import javax.naming.NamingException; @@ -32,6 +31,7 @@ import de.symeda.sormas.api.caze.caseimport.CaseImportFacade; import de.symeda.sormas.api.caze.classification.CaseClassificationFacade; import de.symeda.sormas.api.caze.maternalhistory.MaternalHistoryFacade; +import de.symeda.sormas.api.caze.porthealthinfo.PortHealthInfoFacade; import de.symeda.sormas.api.caze.surveillancereport.SurveillanceReportFacade; import de.symeda.sormas.api.clinicalcourse.ClinicalCourseFacade; import de.symeda.sormas.api.clinicalcourse.ClinicalVisitFacade; diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/caze/porthealthinfo/PortHealthInfoFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/caze/porthealthinfo/PortHealthInfoFacade.java index cd8a9e1610f..c3132b4584a 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/caze/porthealthinfo/PortHealthInfoFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/caze/porthealthinfo/PortHealthInfoFacade.java @@ -5,5 +5,5 @@ @Remote public interface PortHealthInfoFacade { - PortHealthInfoDto getByCaseUuid(String caseUuid); + PortHealthInfoDto getByCaseUuid(String caseUuid); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoFacadeEjb.java index f960098c267..602146f8a42 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoFacadeEjb.java @@ -21,6 +21,9 @@ @Stateless(name = "PortHealthInfoFacade") public class PortHealthInfoFacadeEjb implements PortHealthInfoFacade { + @PersistenceContext(unitName = ModelConstants.PERSISTENCE_UNIT_NAME) + private EntityManager em; + public static PortHealthInfoDto toDto(PortHealthInfo source) { if (source == null) { return null; @@ -84,9 +87,6 @@ public PortHealthInfo fillOrBuildEntity(@NotNull PortHealthInfoDto source, PortH return target; } - @PersistenceContext(unitName = ModelConstants.PERSISTENCE_UNIT_NAME) - protected EntityManager em; - @Override public PortHealthInfoDto getByCaseUuid(String caseUuid) { CriteriaBuilder cb = em.getCriteriaBuilder(); diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/AbstractBeanTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/AbstractBeanTest.java index 3fe45d4c390..6ccd5ef3b96 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/AbstractBeanTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/AbstractBeanTest.java @@ -19,8 +19,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; -import de.symeda.sormas.api.caze.porthealthinfo.PortHealthInfoFacade; -import de.symeda.sormas.backend.caze.porthealthinfo.PortHealthInfoFacadeEjb.PortHealthInfoFacadeEjbLocal; import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.List; @@ -31,6 +29,11 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.function.Executable; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; import de.symeda.sormas.api.ConfigFacade; import de.symeda.sormas.api.Disease; @@ -41,6 +44,7 @@ import de.symeda.sormas.api.campaign.diagram.CampaignDiagramDefinitionFacade; import de.symeda.sormas.api.campaign.form.CampaignFormMetaFacade; import de.symeda.sormas.api.caze.CaseStatisticsFacade; +import de.symeda.sormas.api.caze.porthealthinfo.PortHealthInfoFacade; import de.symeda.sormas.api.caze.surveillancereport.SurveillanceReportFacade; import de.symeda.sormas.api.clinicalcourse.ClinicalCourseFacade; import de.symeda.sormas.api.clinicalcourse.ClinicalVisitFacade; @@ -110,6 +114,7 @@ import de.symeda.sormas.backend.caze.CaseService; import de.symeda.sormas.backend.caze.CaseStatisticsFacadeEjb.CaseStatisticsFacadeEjbLocal; import de.symeda.sormas.backend.caze.classification.CaseClassificationFacadeEjb; +import de.symeda.sormas.backend.caze.porthealthinfo.PortHealthInfoFacadeEjb.PortHealthInfoFacadeEjbLocal; import de.symeda.sormas.backend.caze.surveillancereport.SurveillanceReportFacadeEjb; import de.symeda.sormas.backend.caze.surveillancereport.SurveillanceReportService; import de.symeda.sormas.backend.clinicalcourse.ClinicalCourseFacadeEjb.ClinicalCourseFacadeEjbLocal; @@ -241,11 +246,6 @@ import de.symeda.sormas.backend.visit.VisitService; import info.novatec.beantest.api.BaseBeanTest; import info.novatec.beantest.api.BeanProviderHelper; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.function.Executable; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; @ExtendWith(MockitoExtension.class) @MockitoSettings(strictness = Strictness.LENIENT) diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PointOfEntryFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PointOfEntryFacadeEjbTest.java index a8f5e41883a..f6a714d57f1 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PointOfEntryFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PointOfEntryFacadeEjbTest.java @@ -1,25 +1,23 @@ package de.symeda.sormas.backend.infrastructure; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import de.symeda.sormas.api.caze.CaseDataDto; -import de.symeda.sormas.api.person.PersonDto; -import de.symeda.sormas.api.user.DefaultUserRole; -import de.symeda.sormas.api.user.UserDto; -import de.symeda.sormas.backend.TestDataCreator.RDCF; import java.util.Date; import java.util.List; import org.junit.jupiter.api.Test; +import de.symeda.sormas.api.caze.CaseDataDto; import de.symeda.sormas.api.infrastructure.pointofentry.PointOfEntryCriteria; import de.symeda.sormas.api.infrastructure.pointofentry.PointOfEntryDto; import de.symeda.sormas.api.infrastructure.pointofentry.PointOfEntryFacade; +import de.symeda.sormas.api.person.PersonDto; +import de.symeda.sormas.api.user.DefaultUserRole; +import de.symeda.sormas.api.user.UserDto; import de.symeda.sormas.backend.AbstractBeanTest; +import de.symeda.sormas.backend.TestDataCreator.RDCF; import de.symeda.sormas.backend.infrastructure.district.District; import de.symeda.sormas.backend.infrastructure.region.Region; diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PortHealthInfoFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PortHealthInfoFacadeEjbTest.java index d6760d5b057..47c310b6d61 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PortHealthInfoFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PortHealthInfoFacadeEjbTest.java @@ -35,5 +35,4 @@ public void testGetPortHealthInfoByCaseUuid() { assertEquals(portHealthInfoDto.getUuid(), healthInfoDto.getUuid()); assertEquals(portHealthInfoDto.getAirlineName(), healthInfoDto.getAirlineName()); } - } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java index 4c8715f5ad7..87e3c4d7864 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java @@ -15,7 +15,6 @@ package de.symeda.sormas.ui.caze; -import de.symeda.sormas.api.caze.porthealthinfo.PortHealthInfoDto; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -67,6 +66,7 @@ import de.symeda.sormas.api.caze.classification.ClassificationHtmlRenderer; import de.symeda.sormas.api.caze.classification.DiseaseClassificationCriteriaDto; import de.symeda.sormas.api.caze.maternalhistory.MaternalHistoryDto; +import de.symeda.sormas.api.caze.porthealthinfo.PortHealthInfoDto; import de.symeda.sormas.api.common.DeletionDetails; import de.symeda.sormas.api.common.DeletionReason; import de.symeda.sormas.api.contact.ContactClassification; From 25568bd653dde908c533fe222c88696f3ab272f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=A9=20Strysewske?= Date: Mon, 12 Dec 2022 15:32:25 +0100 Subject: [PATCH 010/166] #6052 - Display side component in all person views --- .../symeda/sormas/ui/caze/CaseDataView.java | 4 +- .../symeda/sormas/ui/caze/CasePersonView.java | 19 ++- .../sormas/ui/caze/caselink/CaseList.java | 6 +- .../ui/caze/caselink/CaseListComponent.java | 3 +- .../sormas/ui/contact/ContactDataView.java | 4 +- .../symeda/sormas/ui/contact/ContactList.java | 3 + .../sormas/ui/contact/ContactListEntry.java | 4 + .../sormas/ui/contact/ContactPersonView.java | 28 ++-- .../ui/contact/contactlink/ContactList.java | 6 +- .../contactlink/ContactListComponent.java | 3 +- .../sormas/ui/epidata/CaseEpiDataView.java | 1 + .../ui/events/EventParticipantDataView.java | 3 +- .../EventParticipantList.java | 6 +- .../EventParticipantListComponent.java | 3 +- .../EventParticipantListEntry.java | 4 + .../immunization/ImmunizationPersonView.java | 18 +- .../immunizationlink/ImmunizationList.java | 6 +- .../ImmunizationListComponent.java | 11 +- .../sormas/ui/person/PersonDataView.java | 116 +------------ .../person/PersonSideComponentsElement.java | 156 ++++++++++++++++++ .../ui/travelentry/TravelEntryPersonView.java | 18 +- .../travelentrylink/TravelEntryList.java | 9 +- .../TravelEntryListComponent.java | 12 +- .../de/symeda/sormas/ui/utils/CssStyles.java | 1 + .../sormas/ui/utils/PaginationList.java | 8 + .../sidecomponent/SideComponentField.java | 4 + .../ui/vaccination/list/VaccinationList.java | 34 ++-- .../list/VaccinationListComponent.java | 10 +- .../webapp/VAADIN/themes/sormas/global.scss | 5 + 29 files changed, 331 insertions(+), 174 deletions(-) create mode 100644 sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonSideComponentsElement.java diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataView.java index 12f92711bca..c51a2793a7e 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataView.java @@ -160,7 +160,7 @@ protected void initView(String params) { layout.addSidePanelComponent(new SideComponentLayout(new ImmunizationListComponent(() -> { CaseDataDto refreshedCase = FacadeProvider.getCaseFacade().getCaseDataByUuid(getCaseRef().getUuid()); return new ImmunizationListCriteria.Builder(refreshedCase.getPerson()).withDisease(refreshedCase.getDisease()).build(); - }, this::showUnsavedChangesPopup, isEditAllowed)), IMMUNIZATION_LOC); + }, null, this::showUnsavedChangesPopup, isEditAllowed)), IMMUNIZATION_LOC); } else { layout.addSidePanelComponent(new SideComponentLayout(new VaccinationListComponent(() -> { CaseDataDto refreshedCase = FacadeProvider.getCaseFacade().getCaseDataByUuid(getCaseRef().getUuid()); @@ -170,7 +170,7 @@ protected void initView(String params) { .caseReference(getCaseRef()) .region(refreshedCase.getResponsibleRegion()) .district(refreshedCase.getResponsibleDistrict()); - }, this::showUnsavedChangesPopup, isEditAllowed)), VACCINATIONS_LOC); + }, null, this::showUnsavedChangesPopup, isEditAllowed)), VACCINATIONS_LOC); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasePersonView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasePersonView.java index 2c90cf2b101..3ad15fc0915 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasePersonView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasePersonView.java @@ -17,20 +17,26 @@ *******************************************************************************/ package de.symeda.sormas.ui.caze; +import com.vaadin.ui.CustomLayout; + import de.symeda.sormas.api.FacadeProvider; import de.symeda.sormas.api.caze.CaseDataDto; +import de.symeda.sormas.api.common.CoreEntityType; import de.symeda.sormas.api.person.PersonContext; import de.symeda.sormas.api.person.PersonDto; import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.ui.ControllerProvider; import de.symeda.sormas.ui.UserProvider; import de.symeda.sormas.ui.person.PersonEditForm; +import de.symeda.sormas.ui.person.PersonSideComponentsElement; import de.symeda.sormas.ui.utils.CommitDiscardWrapperComponent; +import de.symeda.sormas.ui.utils.DetailSubComponentWrapper; @SuppressWarnings("serial") -public class CasePersonView extends AbstractCaseView { +public class CasePersonView extends AbstractCaseView implements PersonSideComponentsElement { public static final String VIEW_NAME = ROOT_VIEW_NAME + "/person"; + private PersonDto person; public CasePersonView() { @@ -42,8 +48,7 @@ protected void initView(String params) { CaseDataDto caseData = FacadeProvider.getCaseFacade().getCaseDataByUuid(getCaseRef().getUuid()); person = FacadeProvider.getPersonFacade().getByUuid(caseData.getPerson().getUuid()); - - CommitDiscardWrapperComponent personEditComponent = ControllerProvider.getPersonController() + CommitDiscardWrapperComponent editComponent = ControllerProvider.getPersonController() .getPersonEditComponent( PersonContext.CASE, person, @@ -52,10 +57,12 @@ protected void initView(String params) { UserRight.CASE_EDIT, getViewMode(), isEditAllowed()); - - setSubComponent(personEditComponent); + DetailSubComponentWrapper componentWrapper = addComponentWrapper(editComponent); + CustomLayout layout = addPageLayout(componentWrapper, editComponent); + setSubComponent(componentWrapper); + addSideComponents(layout, CoreEntityType.CASE, caseData.getUuid(), person.toReference(), this::showUnsavedChangesPopup); setEditPermission( - personEditComponent, + editComponent, UserProvider.getCurrent().hasUserRight(UserRight.PERSON_EDIT), PersonDto.ADDRESSES, PersonDto.PERSON_CONTACT_DETAILS); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/caselink/CaseList.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/caselink/CaseList.java index 44eccab7a93..6a4f6c113f5 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/caselink/CaseList.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/caselink/CaseList.java @@ -49,7 +49,11 @@ protected void drawDisplayedEntries() { for (int i = 0, displayedEntriesSize = displayedEntries.size(); i < displayedEntriesSize; i++) { final CaseListEntryDto caze = displayedEntries.get(i); final CaseListEntry listEntry = new CaseListEntry(caze); - if (currentUser != null && currentUser.hasUserRight(UserRight.CASE_EDIT)) { + final boolean isActiveCase = caze.getUuid().equals(getActiveUuid()); + if (isActiveCase) { + listEntry.setActive(); + } + if (currentUser != null && currentUser.hasUserRight(UserRight.CASE_EDIT) && !isActiveCase) { listEntry.addEditButton( "edit-case-" + i, (Button.ClickListener) event -> ControllerProvider.getCaseController().navigateToCase(listEntry.getCaseListEntryDto().getUuid())); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/caselink/CaseListComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/caselink/CaseListComponent.java index 9ec93753043..7cf7f6f17a7 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/caselink/CaseListComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/caselink/CaseListComponent.java @@ -19,7 +19,7 @@ public class CaseListComponent extends SideComponent { - public CaseListComponent(PersonReferenceDto personReferenceDto, Consumer actionCallback) { + public CaseListComponent(PersonReferenceDto personReferenceDto, String activeUuid, Consumer actionCallback) { super(I18nProperties.getString(Strings.entityCases), actionCallback); @@ -28,6 +28,7 @@ public CaseListComponent(PersonReferenceDto personReferenceDto, Consumer { ContactDto refreshedContact = FacadeProvider.getContactFacade().getByUuid(getContactRef().getUuid()); return new ImmunizationListCriteria.Builder(refreshedContact.getPerson()).withDisease(refreshedContact.getDisease()).build(); - }, this::showUnsavedChangesPopup, isEditAllowed())), IMMUNIZATION_LOC); + }, null, this::showUnsavedChangesPopup, isEditAllowed())), IMMUNIZATION_LOC); } else { layout.addSidePanelComponent(new SideComponentLayout(new VaccinationListComponent(() -> { ContactDto refreshedContact = FacadeProvider.getContactFacade().getByUuid(getContactRef().getUuid()); @@ -249,7 +249,7 @@ protected void initView(String params) { .contactReference(getContactRef()) .region(refreshedContact.getRegion() != null ? refreshedContact.getRegion() : refreshedCase.getResponsibleRegion()) .district(refreshedContact.getDistrict() != null ? refreshedContact.getDistrict() : refreshedCase.getResponsibleDistrict()); - }, this::showUnsavedChangesPopup, isEditAllowed())), VACCINATIONS_LOC); + }, null, this::showUnsavedChangesPopup, isEditAllowed())), VACCINATIONS_LOC); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactList.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactList.java index 61645590c29..c751be2964e 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactList.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactList.java @@ -65,6 +65,9 @@ protected void drawDisplayedEntries() { for (int i = 0, displayedEntriesSize = displayedEntries.size(); i < displayedEntriesSize; i++) { ContactIndexDto contact = displayedEntries.get(i); ContactListEntry listEntry = new ContactListEntry(contact); + if (contact.getUuid().equals(getActiveUuid())) { + listEntry.setActive(); + } if (UserProvider.getCurrent().hasUserRight(UserRight.CONTACT_DELETE)) { listEntry.addDeleteListener( diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactListEntry.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactListEntry.java index 59f0eeaced2..59529dd29a8 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactListEntry.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactListEntry.java @@ -122,6 +122,10 @@ public void addDeleteListener(int rowIndex, ClickListener deleteClickListener) { deleteButton.addClickListener(deleteClickListener); } + public void setActive() { + addStyleName(CssStyles.ACTIVE_SIDE_COMPONENT_ELEMENT); + } + public ContactIndexDto getContact() { return contact; } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactPersonView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactPersonView.java index 2a4b7844821..f166c67ab85 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactPersonView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactPersonView.java @@ -17,7 +17,10 @@ *******************************************************************************/ package de.symeda.sormas.ui.contact; +import com.vaadin.ui.CustomLayout; + import de.symeda.sormas.api.FacadeProvider; +import de.symeda.sormas.api.common.CoreEntityType; import de.symeda.sormas.api.contact.ContactDto; import de.symeda.sormas.api.person.PersonContext; import de.symeda.sormas.api.person.PersonDto; @@ -25,9 +28,11 @@ import de.symeda.sormas.ui.ControllerProvider; import de.symeda.sormas.ui.UserProvider; import de.symeda.sormas.ui.person.PersonEditForm; +import de.symeda.sormas.ui.person.PersonSideComponentsElement; import de.symeda.sormas.ui.utils.CommitDiscardWrapperComponent; +import de.symeda.sormas.ui.utils.DetailSubComponentWrapper; -public class ContactPersonView extends AbstractContactView { +public class ContactPersonView extends AbstractContactView implements PersonSideComponentsElement { private static final long serialVersionUID = -1L; @@ -42,22 +47,23 @@ public ContactPersonView() { @Override protected void initView(String params) { - ContactDto caze = FacadeProvider.getContactFacade().getByUuid(getContactRef().getUuid()); - person = FacadeProvider.getPersonFacade().getByUuid(caze.getPerson().getUuid()); - - CommitDiscardWrapperComponent contactPersonComponent = ControllerProvider.getPersonController() + ContactDto contact = FacadeProvider.getContactFacade().getByUuid(getContactRef().getUuid()); + person = FacadeProvider.getPersonFacade().getByUuid(contact.getPerson().getUuid()); + CommitDiscardWrapperComponent editComponent = ControllerProvider.getPersonController() .getPersonEditComponent( - PersonContext.CONTACT, + PersonContext.CASE, person, - caze.getDisease(), - caze.getDiseaseDetails(), + contact.getDisease(), + contact.getDiseaseDetails(), UserRight.CONTACT_EDIT, null, isEditAllowed()); - setSubComponent(contactPersonComponent); - + DetailSubComponentWrapper componentWrapper = addComponentWrapper(editComponent); + CustomLayout layout = addPageLayout(componentWrapper, editComponent); + setSubComponent(componentWrapper); + addSideComponents(layout, CoreEntityType.CONTACT, contact.getUuid(), person.toReference(), this::showUnsavedChangesPopup); setEditPermission( - contactPersonComponent, + editComponent, UserProvider.getCurrent().hasUserRight(UserRight.PERSON_EDIT), PersonDto.ADDRESSES, PersonDto.PERSON_CONTACT_DETAILS); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/contactlink/ContactList.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/contactlink/ContactList.java index ad4ba324398..71ffe715181 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/contactlink/ContactList.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/contactlink/ContactList.java @@ -49,7 +49,11 @@ protected void drawDisplayedEntries() { for (int i = 0, displayedEntriesSize = displayedEntries.size(); i < displayedEntriesSize; i++) { final ContactListEntryDto contactListEntryDto = displayedEntries.get(i); final ContactListEntry listEntry = new ContactListEntry(contactListEntryDto); - if (currentUser != null && currentUser.hasUserRight(UserRight.CONTACT_EDIT)) { + final boolean isActiveContact = contactListEntryDto.getUuid().equals(getActiveUuid()); + if (isActiveContact) { + listEntry.setActive(); + } + if (currentUser != null && currentUser.hasUserRight(UserRight.CONTACT_EDIT) && !isActiveContact) { listEntry.addEditButton( "edit-contact-" + i, (Button.ClickListener) event -> ControllerProvider.getContactController() diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/contactlink/ContactListComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/contactlink/ContactListComponent.java index 601dd0736ab..974ee302b73 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/contactlink/ContactListComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/contactlink/ContactListComponent.java @@ -19,7 +19,7 @@ public class ContactListComponent extends SideComponent { - public ContactListComponent(PersonReferenceDto personReferenceDto, Consumer actionCallback) { + public ContactListComponent(PersonReferenceDto personReferenceDto, String activeUuid, Consumer actionCallback) { super(I18nProperties.getString(Strings.entityContacts), actionCallback); addCreateButton(I18nProperties.getCaption(Captions.contactNewContact), () -> { @@ -27,6 +27,7 @@ public ContactListComponent(PersonReferenceDto personReferenceDto, Consumer new ImmunizationListCriteria.Builder(eventParticipant.getPerson().toReference()).withDisease(event.getDisease()) .build(), + null, this::showUnsavedChangesPopup)), IMMUNIZATION_LOC); } else { @@ -201,7 +202,7 @@ protected void initView(String params) { .eventParticipantReference(getReference()) .region(region) .district(district); - }, this::showUnsavedChangesPopup, true)), VACCINATIONS_LOC); + }, null, this::showUnsavedChangesPopup, true)), VACCINATIONS_LOC); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/eventParticipantLink/EventParticipantList.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/eventParticipantLink/EventParticipantList.java index f10aad3309d..5c8974471c3 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/eventParticipantLink/EventParticipantList.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/eventParticipantLink/EventParticipantList.java @@ -48,7 +48,11 @@ protected void drawDisplayedEntries() { for (int i = 0, displayedEntriesSize = displayedEntries.size(); i < displayedEntriesSize; i++) { final EventParticipantListEntryDto eventParticipant = displayedEntries.get(i); final EventParticipantListEntry listEntry = new EventParticipantListEntry(eventParticipant); - if (UserProvider.getCurrent().hasUserRight(UserRight.EVENTPARTICIPANT_EDIT)) { + boolean isActiveEventParticipant = eventParticipant.getUuid().equals(getActiveUuid()); + if (isActiveEventParticipant) { + listEntry.setActive(); + } + if (UserProvider.getCurrent().hasUserRight(UserRight.EVENTPARTICIPANT_EDIT) && !isActiveEventParticipant) { listEntry.addEditListener( i, (Button.ClickListener) event -> ControllerProvider.getEventParticipantController() diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/eventParticipantLink/EventParticipantListComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/eventParticipantLink/EventParticipantListComponent.java index ec01e7178b5..f2386fc0544 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/eventParticipantLink/EventParticipantListComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/eventParticipantLink/EventParticipantListComponent.java @@ -20,7 +20,7 @@ public class EventParticipantListComponent extends SideComponent { - public EventParticipantListComponent(PersonReferenceDto personReferenceDto, Consumer actionCallback) { + public EventParticipantListComponent(PersonReferenceDto personReferenceDto, String activeUuid, Consumer actionCallback) { super(I18nProperties.getString(Strings.entityEvents), actionCallback); addCreateButton(I18nProperties.getCaption(Captions.linkEvent), () -> { @@ -36,6 +36,7 @@ public EventParticipantListComponent(PersonReferenceDto personReferenceDto, Cons }, UserRight.EVENTPARTICIPANT_CREATE); EventParticipantList eventParticipantList = new EventParticipantList(personReferenceDto); + eventParticipantList.setActiveUuid(activeUuid); addComponent(eventParticipantList); eventParticipantList.reload(); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/eventParticipantLink/EventParticipantListEntry.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/eventParticipantLink/EventParticipantListEntry.java index d712c8fa5d5..6138ec17c7d 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/eventParticipantLink/EventParticipantListEntry.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/eventParticipantLink/EventParticipantListEntry.java @@ -117,6 +117,10 @@ public void addEditListener(int rowIndex, Button.ClickListener editClickListener editButton.addClickListener(editClickListener); } + public void setActive() { + addStyleName(CssStyles.ACTIVE_SIDE_COMPONENT_ELEMENT); + } + public EventParticipantListEntryDto getEventParticipantListEntryDto() { return eventParticipantListEntryDto; } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/ImmunizationPersonView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/ImmunizationPersonView.java index 8ca2186b2d7..8553dfad2da 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/ImmunizationPersonView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/ImmunizationPersonView.java @@ -1,15 +1,20 @@ package de.symeda.sormas.ui.immunization; +import com.vaadin.ui.CustomLayout; + import de.symeda.sormas.api.FacadeProvider; +import de.symeda.sormas.api.common.CoreEntityType; import de.symeda.sormas.api.immunization.ImmunizationDto; import de.symeda.sormas.api.person.PersonContext; import de.symeda.sormas.api.person.PersonDto; import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.ui.ControllerProvider; import de.symeda.sormas.ui.person.PersonEditForm; +import de.symeda.sormas.ui.person.PersonSideComponentsElement; import de.symeda.sormas.ui.utils.CommitDiscardWrapperComponent; +import de.symeda.sormas.ui.utils.DetailSubComponentWrapper; -public class ImmunizationPersonView extends AbstractImmunizationView { +public class ImmunizationPersonView extends AbstractImmunizationView implements PersonSideComponentsElement { public static final String VIEW_NAME = ROOT_VIEW_NAME + "/person"; @@ -24,12 +29,13 @@ protected void initView(String params) { ImmunizationDto immunzation = FacadeProvider.getImmunizationFacade().getByUuid(getReference().getUuid()); person = FacadeProvider.getPersonFacade().getByUuid(immunzation.getPerson().getUuid()); - - CommitDiscardWrapperComponent immunizationPersonComponent = ControllerProvider.getPersonController() + CommitDiscardWrapperComponent editComponent = ControllerProvider.getPersonController() .getPersonEditComponent(PersonContext.IMMUNIZATION, person, immunzation.getDisease(), null, UserRight.PERSON_EDIT, null); - setSubComponent(immunizationPersonComponent); - - setEditPermission(immunizationPersonComponent); + DetailSubComponentWrapper componentWrapper = addComponentWrapper(editComponent); + CustomLayout layout = addPageLayout(componentWrapper, editComponent); + setSubComponent(componentWrapper); + addSideComponents(layout, CoreEntityType.IMMUNIZATION, immunzation.getUuid(), person.toReference(), this::showUnsavedChangesPopup); + setEditPermission(editComponent); } @Override diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/immunizationlink/ImmunizationList.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/immunizationlink/ImmunizationList.java index 8cfb9e8fe13..ff259a7ddc8 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/immunizationlink/ImmunizationList.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/immunizationlink/ImmunizationList.java @@ -48,7 +48,11 @@ protected void drawDisplayedEntries() { UserProvider currentUser = UserProvider.getCurrent(); for (ImmunizationListEntryDto immunization : getDisplayedEntries()) { ImmunizationListEntry listEntry = new ImmunizationListEntry(immunization); - if (currentUser != null) { + boolean isActiveImmunization = immunization.getUuid().equals(getActiveUuid()); + if (isActiveImmunization) { + listEntry.setActive(); + } + if (currentUser != null && !isActiveImmunization) { boolean isEditableAndHasEditRight = isEditAllowed && currentUser.hasUserRight(UserRight.IMMUNIZATION_EDIT); listEntry.addActionButton( listEntry.getImmunizationEntry().getUuid(), diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/immunizationlink/ImmunizationListComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/immunizationlink/ImmunizationListComponent.java index 8492d0fd042..1c55c00e3b8 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/immunizationlink/ImmunizationListComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/immunizationlink/ImmunizationListComponent.java @@ -13,11 +13,15 @@ public class ImmunizationListComponent extends SideComponent { - public ImmunizationListComponent(Supplier criteriaSupplier, Consumer actionCallback) { - this(criteriaSupplier, actionCallback, true); + public ImmunizationListComponent(Supplier criteriaSupplier, String activeUuid, Consumer actionCallback) { + this(criteriaSupplier, activeUuid, actionCallback, true); } - public ImmunizationListComponent(Supplier criteriaSupplier, Consumer actionCallback, boolean isEditAllowed) { + public ImmunizationListComponent( + Supplier criteriaSupplier, + String activeUuid, + Consumer actionCallback, + boolean isEditAllowed) { super(I18nProperties.getString(Strings.entityImmunization), actionCallback); if (isEditAllowed) { @@ -27,6 +31,7 @@ public ImmunizationListComponent(Supplier criteriaSupp }, UserRight.IMMUNIZATION_CREATE); } ImmunizationList immunizationList = new ImmunizationList(criteriaSupplier.get(), isEditAllowed); + immunizationList.setActiveUuid(activeUuid); addComponent(immunizationList); immunizationList.reload(); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonDataView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonDataView.java index 8c17e47d1d7..c483c926b80 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonDataView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonDataView.java @@ -3,49 +3,24 @@ import com.vaadin.navigator.ViewChangeListener; import com.vaadin.ui.CustomLayout; -import de.symeda.sormas.api.CountryHelper; import de.symeda.sormas.api.FacadeProvider; -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.immunization.ImmunizationListCriteria; import de.symeda.sormas.api.person.PersonDto; import de.symeda.sormas.api.person.PersonReferenceDto; -import de.symeda.sormas.api.travelentry.TravelEntryListCriteria; import de.symeda.sormas.api.user.UserRight; -import de.symeda.sormas.api.vaccination.VaccinationCriteria; import de.symeda.sormas.ui.ControllerProvider; import de.symeda.sormas.ui.SubMenu; import de.symeda.sormas.ui.UserProvider; -import de.symeda.sormas.ui.caze.caselink.CaseListComponent; -import de.symeda.sormas.ui.contact.contactlink.ContactListComponent; -import de.symeda.sormas.ui.events.eventParticipantLink.EventParticipantListComponent; -import de.symeda.sormas.ui.immunization.immunizationlink.ImmunizationListComponent; -import de.symeda.sormas.ui.travelentry.travelentrylink.TravelEntryListComponent; import de.symeda.sormas.ui.utils.AbstractDetailView; import de.symeda.sormas.ui.utils.CommitDiscardWrapperComponent; -import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.DetailSubComponentWrapper; import de.symeda.sormas.ui.utils.DirtyStateComponent; -import de.symeda.sormas.ui.utils.LayoutUtil; -import de.symeda.sormas.ui.utils.components.sidecomponent.SideComponentLayout; -import de.symeda.sormas.ui.vaccination.list.VaccinationListComponent; -public class PersonDataView extends AbstractDetailView { +public class PersonDataView extends AbstractDetailView implements PersonSideComponentsElement { public static final String VIEW_NAME = PersonsView.VIEW_NAME + "/data"; - public static final String PERSON_LOC = "person"; - public static final String CASES_LOC = "cases"; - public static final String CONTACTS_LOC = "contacts"; - public static final String EVENT_PARTICIPANTS_LOC = "events"; - public static final String TRAVEL_ENTRIES_LOC = "travelEntries"; - public static final String IMMUNIZATION_LOC = "immunizations"; - public static final String VACCINATIONS_LOC = "vaccinations"; - - private CommitDiscardWrapperComponent editComponent; - public PersonDataView() { super(VIEW_NAME); } @@ -70,89 +45,12 @@ protected String getRootViewName() { protected void initView(String params) { setHeightUndefined(); - - String htmlLayout = LayoutUtil.fluidRow( - LayoutUtil.fluidColumnLoc(8, 0, 12, 0, PERSON_LOC), - LayoutUtil.fluidColumnLoc(4, 0, 6, 0, CASES_LOC), - LayoutUtil.fluidColumnLoc(4, 0, 6, 0, CONTACTS_LOC), - LayoutUtil.fluidColumnLoc(4, 0, 6, 0, EVENT_PARTICIPANTS_LOC), - LayoutUtil.fluidColumnLoc(4, 0, 6, 0, TRAVEL_ENTRIES_LOC), - LayoutUtil.fluidColumnLoc(4, 0, 6, 0, IMMUNIZATION_LOC), - LayoutUtil.fluidColumnLoc(4, 0, 6, 0, VACCINATIONS_LOC)); - - DetailSubComponentWrapper container = new DetailSubComponentWrapper(() -> editComponent); - container.setWidth(100, Unit.PERCENTAGE); - container.setMargin(true); - setSubComponent(container); - CustomLayout layout = new CustomLayout(); - layout.addStyleName(CssStyles.ROOT_COMPONENT); - layout.setTemplateContents(htmlLayout); - layout.setWidth(100, Unit.PERCENTAGE); - layout.setHeightUndefined(); - container.addComponent(layout); - - editComponent = ControllerProvider.getPersonController().getPersonEditComponent(getReference().getUuid(), UserRight.PERSON_EDIT); - editComponent.setMargin(false); - editComponent.setWidth(100, Unit.PERCENTAGE); - editComponent.getWrappedComponent().setWidth(100, Unit.PERCENTAGE); - editComponent.addStyleName(CssStyles.MAIN_COMPONENT); - layout.addComponent(editComponent, PERSON_LOC); - - UserProvider currentUser = UserProvider.getCurrent(); - - if (FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.CASE_SURVEILANCE) - && currentUser != null - && currentUser.hasUserRight(UserRight.CASE_VIEW)) { - layout.addComponent(new SideComponentLayout(new CaseListComponent(getReference(), this::showUnsavedChangesPopup)), CASES_LOC); - } - - if (FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.CONTACT_TRACING) - && currentUser != null - && currentUser.hasUserRight(UserRight.CONTACT_VIEW)) { - layout.addComponent(new SideComponentLayout(new ContactListComponent(getReference(), this::showUnsavedChangesPopup)), CONTACTS_LOC); - } - - if (FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.EVENT_SURVEILLANCE) - && currentUser != null - && currentUser.hasUserRight(UserRight.EVENT_VIEW) - && currentUser.hasUserRight(UserRight.EVENTPARTICIPANT_VIEW)) { - layout.addComponent( - new SideComponentLayout(new EventParticipantListComponent(getReference(), this::showUnsavedChangesPopup)), - EVENT_PARTICIPANTS_LOC); - } - - if (FacadeProvider.getConfigFacade().isConfiguredCountry(CountryHelper.COUNTRY_CODE_GERMANY) - && FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.TRAVEL_ENTRIES) - && currentUser != null - && currentUser.hasUserRight(UserRight.TRAVEL_ENTRY_VIEW)) { - TravelEntryListCriteria travelEntryListCriteria = new TravelEntryListCriteria.Builder().withPerson(getReference()).build(); - layout.addComponent( - new SideComponentLayout(new TravelEntryListComponent(travelEntryListCriteria, this::showUnsavedChangesPopup)), - TRAVEL_ENTRIES_LOC); - } - - if (FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.IMMUNIZATION_MANAGEMENT) - && currentUser != null - && currentUser.hasUserRight(UserRight.IMMUNIZATION_VIEW)) { - if (!FacadeProvider.getFeatureConfigurationFacade() - .isPropertyValueTrue(FeatureType.IMMUNIZATION_MANAGEMENT, FeatureTypeProperty.REDUCED)) { - layout.addComponent( - new SideComponentLayout( - new ImmunizationListComponent( - () -> new ImmunizationListCriteria.Builder(getReference()).build(), - this::showUnsavedChangesPopup)), - IMMUNIZATION_LOC); - } else { - layout.addComponent( - new SideComponentLayout( - new VaccinationListComponent( - () -> new VaccinationCriteria.Builder(getReference()).build(), - this::showUnsavedChangesPopup, - false, - true)), - VACCINATIONS_LOC); - } - } + CommitDiscardWrapperComponent editComponent = + ControllerProvider.getPersonController().getPersonEditComponent(getReference().getUuid(), UserRight.PERSON_EDIT); + DetailSubComponentWrapper componentWrapper = addComponentWrapper(editComponent); + CustomLayout layout = addPageLayout(componentWrapper, editComponent); + setSubComponent(componentWrapper); + addSideComponents(layout, null, null, getReference(), this::showUnsavedChangesPopup); } @Override diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonSideComponentsElement.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonSideComponentsElement.java new file mode 100644 index 00000000000..36656dc6cd7 --- /dev/null +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonSideComponentsElement.java @@ -0,0 +1,156 @@ +package de.symeda.sormas.ui.person; + +import java.util.function.Consumer; + +import com.vaadin.server.Sizeable; +import com.vaadin.ui.CustomLayout; + +import de.symeda.sormas.api.CountryHelper; +import de.symeda.sormas.api.FacadeProvider; +import de.symeda.sormas.api.common.CoreEntityType; +import de.symeda.sormas.api.feature.FeatureType; +import de.symeda.sormas.api.feature.FeatureTypeProperty; +import de.symeda.sormas.api.immunization.ImmunizationListCriteria; +import de.symeda.sormas.api.person.PersonReferenceDto; +import de.symeda.sormas.api.travelentry.TravelEntryListCriteria; +import de.symeda.sormas.api.user.UserRight; +import de.symeda.sormas.api.vaccination.VaccinationCriteria; +import de.symeda.sormas.ui.UserProvider; +import de.symeda.sormas.ui.caze.caselink.CaseListComponent; +import de.symeda.sormas.ui.contact.contactlink.ContactListComponent; +import de.symeda.sormas.ui.events.eventParticipantLink.EventParticipantListComponent; +import de.symeda.sormas.ui.immunization.immunizationlink.ImmunizationListComponent; +import de.symeda.sormas.ui.travelentry.travelentrylink.TravelEntryListComponent; +import de.symeda.sormas.ui.utils.CommitDiscardWrapperComponent; +import de.symeda.sormas.ui.utils.CssStyles; +import de.symeda.sormas.ui.utils.DetailSubComponentWrapper; +import de.symeda.sormas.ui.utils.LayoutUtil; +import de.symeda.sormas.ui.utils.components.sidecomponent.SideComponentLayout; +import de.symeda.sormas.ui.vaccination.list.VaccinationListComponent; + +public interface PersonSideComponentsElement { + + String PERSON_LOC = "person"; + String CASES_LOC = "cases"; + String CONTACTS_LOC = "contacts"; + String EVENT_PARTICIPANTS_LOC = "events"; + String TRAVEL_ENTRIES_LOC = "travelEntries"; + String IMMUNIZATION_LOC = "immunizations"; + String VACCINATIONS_LOC = "vaccinations"; + + default String getHtmlLayout() { + return LayoutUtil.fluidRow( + LayoutUtil.fluidColumnLoc(8, 0, 12, 0, PERSON_LOC), + LayoutUtil.fluidColumnLoc(4, 0, 6, 0, CASES_LOC), + LayoutUtil.fluidColumnLoc(4, 0, 6, 0, CONTACTS_LOC), + LayoutUtil.fluidColumnLoc(4, 0, 6, 0, EVENT_PARTICIPANTS_LOC), + LayoutUtil.fluidColumnLoc(4, 0, 6, 0, TRAVEL_ENTRIES_LOC), + LayoutUtil.fluidColumnLoc(4, 0, 6, 0, IMMUNIZATION_LOC), + LayoutUtil.fluidColumnLoc(4, 0, 6, 0, VACCINATIONS_LOC)); + } + + default DetailSubComponentWrapper addComponentWrapper(CommitDiscardWrapperComponent personComponent) { + + DetailSubComponentWrapper container = new DetailSubComponentWrapper(() -> personComponent); + container.setWidth(100, Sizeable.Unit.PERCENTAGE); + container.setMargin(true); + return container; + } + + default CustomLayout addPageLayout(DetailSubComponentWrapper container, CommitDiscardWrapperComponent personComponent) { + + CustomLayout layout = new CustomLayout(); + layout.addStyleName(CssStyles.ROOT_COMPONENT); + layout.setTemplateContents(getHtmlLayout()); + layout.setWidth(100, Sizeable.Unit.PERCENTAGE); + layout.setHeightUndefined(); + container.addComponent(layout); + personComponent.setMargin(false); + personComponent.setWidth(100, Sizeable.Unit.PERCENTAGE); + personComponent.getWrappedComponent().setWidth(100, Sizeable.Unit.PERCENTAGE); + personComponent.addStyleName(CssStyles.MAIN_COMPONENT); + layout.addComponent(personComponent, PERSON_LOC); + return layout; + } + + default void addSideComponents( + CustomLayout layout, + CoreEntityType entityType, + String entityUuid, + PersonReferenceDto person, + Consumer showUnsavedChangesPopup) { + + UserProvider currentUser = UserProvider.getCurrent(); + + if (FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.CASE_SURVEILANCE) + && currentUser != null + && currentUser.hasUserRight(UserRight.CASE_VIEW)) { + layout.addComponent( + new SideComponentLayout( + new CaseListComponent(person, entityType == CoreEntityType.CASE ? entityUuid : null, showUnsavedChangesPopup)), + CASES_LOC); + } + + if (FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.CONTACT_TRACING) + && currentUser != null + && currentUser.hasUserRight(UserRight.CONTACT_VIEW)) { + layout.addComponent( + new SideComponentLayout( + new ContactListComponent(person, entityType == CoreEntityType.CONTACT ? entityUuid : null, showUnsavedChangesPopup)), + CONTACTS_LOC); + } + + if (FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.EVENT_SURVEILLANCE) + && currentUser != null + && currentUser.hasUserRight(UserRight.EVENT_VIEW) + && currentUser.hasUserRight(UserRight.EVENTPARTICIPANT_VIEW)) { + layout.addComponent( + new SideComponentLayout( + new EventParticipantListComponent( + person, + entityType == CoreEntityType.EVENT_PARTICIPANT ? entityUuid : null, + showUnsavedChangesPopup)), + EVENT_PARTICIPANTS_LOC); + } + + if (FacadeProvider.getConfigFacade().isConfiguredCountry(CountryHelper.COUNTRY_CODE_GERMANY) + && FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.TRAVEL_ENTRIES) + && currentUser != null + && currentUser.hasUserRight(UserRight.TRAVEL_ENTRY_VIEW)) { + TravelEntryListCriteria travelEntryListCriteria = new TravelEntryListCriteria.Builder().withPerson(person).build(); + layout.addComponent( + new SideComponentLayout( + new TravelEntryListComponent( + travelEntryListCriteria, + entityType == CoreEntityType.TRAVEL_ENTRY ? entityUuid : null, + showUnsavedChangesPopup)), + TRAVEL_ENTRIES_LOC); + } + + if (FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.IMMUNIZATION_MANAGEMENT) + && currentUser != null + && currentUser.hasUserRight(UserRight.IMMUNIZATION_VIEW)) { + if (!FacadeProvider.getFeatureConfigurationFacade() + .isPropertyValueTrue(FeatureType.IMMUNIZATION_MANAGEMENT, FeatureTypeProperty.REDUCED)) { + layout.addComponent( + new SideComponentLayout( + new ImmunizationListComponent( + () -> new ImmunizationListCriteria.Builder(person).build(), + entityType == CoreEntityType.IMMUNIZATION ? entityUuid : null, + showUnsavedChangesPopup)), + IMMUNIZATION_LOC); + } else { + layout.addComponent( + new SideComponentLayout( + new VaccinationListComponent( + () -> new VaccinationCriteria.Builder(person).build(), + entityType == CoreEntityType.IMMUNIZATION ? entityUuid : null, + showUnsavedChangesPopup, + false, + true)), + VACCINATIONS_LOC); + } + } + } + +} diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryPersonView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryPersonView.java index 102d022c374..6ebd5716372 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryPersonView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryPersonView.java @@ -1,15 +1,20 @@ package de.symeda.sormas.ui.travelentry; +import com.vaadin.ui.CustomLayout; + import de.symeda.sormas.api.FacadeProvider; +import de.symeda.sormas.api.common.CoreEntityType; import de.symeda.sormas.api.person.PersonContext; import de.symeda.sormas.api.person.PersonDto; import de.symeda.sormas.api.travelentry.TravelEntryDto; import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.ui.ControllerProvider; import de.symeda.sormas.ui.person.PersonEditForm; +import de.symeda.sormas.ui.person.PersonSideComponentsElement; import de.symeda.sormas.ui.utils.CommitDiscardWrapperComponent; +import de.symeda.sormas.ui.utils.DetailSubComponentWrapper; -public class TravelEntryPersonView extends AbstractTravelEntryView { +public class TravelEntryPersonView extends AbstractTravelEntryView implements PersonSideComponentsElement { public static final String VIEW_NAME = ROOT_VIEW_NAME + "/person"; @@ -24,8 +29,7 @@ protected void initView(String params) { TravelEntryDto travelEntry = FacadeProvider.getTravelEntryFacade().getByUuid(getReference().getUuid()); person = FacadeProvider.getPersonFacade().getByUuid(travelEntry.getPerson().getUuid()); - - CommitDiscardWrapperComponent travelEntryPersonComponent = ControllerProvider.getPersonController() + CommitDiscardWrapperComponent editComponent = ControllerProvider.getPersonController() .getPersonEditComponent( PersonContext.TRAVEL_ENTRY, person, @@ -33,9 +37,11 @@ protected void initView(String params) { travelEntry.getDiseaseDetails(), UserRight.PERSON_EDIT, null); - setSubComponent(travelEntryPersonComponent); - - setEditPermission(travelEntryPersonComponent); + DetailSubComponentWrapper componentWrapper = addComponentWrapper(editComponent); + CustomLayout layout = addPageLayout(componentWrapper, editComponent); + setSubComponent(componentWrapper); + addSideComponents(layout, CoreEntityType.TRAVEL_ENTRY, travelEntry.getUuid(), person.toReference(), this::showUnsavedChangesPopup); + setEditPermission(editComponent); } @Override diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/travelentrylink/TravelEntryList.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/travelentrylink/TravelEntryList.java index 5ff0b2ee669..c997ca34fd6 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/travelentrylink/TravelEntryList.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/travelentrylink/TravelEntryList.java @@ -63,8 +63,13 @@ public void reload() { protected void drawDisplayedEntries() { for (TravelEntryListEntryDto travelEntry : getDisplayedEntries()) { TravelEntryListEntry listEntry = new TravelEntryListEntry(travelEntry); - - addActionButton(listEntry); + boolean isActiveTravelEntry = travelEntry.getUuid().equals(getActiveUuid()); + if (isActiveTravelEntry) { + listEntry.setActive(); + } + if (!isActiveTravelEntry) { + addActionButton(listEntry); + } listLayout.addComponent(listEntry); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/travelentrylink/TravelEntryListComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/travelentrylink/TravelEntryListComponent.java index 12bacdf3f24..151e4869c02 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/travelentrylink/TravelEntryListComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/travelentrylink/TravelEntryListComponent.java @@ -29,7 +29,7 @@ public class TravelEntryListComponent extends SideComponent { - public TravelEntryListComponent(TravelEntryListCriteria travelEntryListCriteria, Consumer actionCallback) { + public TravelEntryListComponent(TravelEntryListCriteria travelEntryListCriteria, String activeUuid, Consumer actionCallback) { super(I18nProperties.getString(Strings.entityTravelEntries), actionCallback); if (FacadeProvider.getTravelEntryFacade().count(new TravelEntryCriteria(), true) > 0) { @@ -40,14 +40,19 @@ public TravelEntryListComponent(TravelEntryListCriteria travelEntryListCriteria, } TravelEntryList travelEntryList = new TravelEntryList(travelEntryListCriteria, true); + travelEntryList.setActiveUuid(activeUuid); addComponent(travelEntryList); travelEntryList.reload(); } - public TravelEntryListComponent(TravelEntryListCriteria travelEntryListCriteria, Consumer actionCallback, boolean isEditAllowed) { + public TravelEntryListComponent( + TravelEntryListCriteria travelEntryListCriteria, + String activeUuid, + Consumer actionCallback, + boolean isEditAllowed) { super(I18nProperties.getString(Strings.entityTravelEntries), actionCallback); - if (FacadeProvider.getTravelEntryFacade().count(new TravelEntryCriteria(), true) > 0 && isEditAllowed) { + if (activeUuid == null && FacadeProvider.getTravelEntryFacade().count(new TravelEntryCriteria(), true) > 0 && isEditAllowed) { addCreateButton( I18nProperties.getCaption(Captions.travelEntryNewTravelEntry), () -> ControllerProvider.getTravelEntryController().create(travelEntryListCriteria), @@ -55,6 +60,7 @@ public TravelEntryListComponent(TravelEntryListCriteria travelEntryListCriteria, } TravelEntryList travelEntryList = new TravelEntryList(travelEntryListCriteria, isEditAllowed); + travelEntryList.setActiveUuid(activeUuid); addComponent(travelEntryList); travelEntryList.reload(); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CssStyles.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CssStyles.java index 00e2569c19a..c59d202828a 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CssStyles.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CssStyles.java @@ -271,6 +271,7 @@ private CssStyles() { // MISC public static final String RESIZABLE = "resizable"; + public static final String ACTIVE_SIDE_COMPONENT_ELEMENT = "active-side-component-element"; // Grid layout public static final String GRID_LAYOUT_EVEN = "even"; diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/PaginationList.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/PaginationList.java index bdf95a07857..86de2cc4009 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/PaginationList.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/PaginationList.java @@ -46,6 +46,7 @@ public abstract class PaginationList extends VerticalLayout { private List entries; private List displayedEntries; private int currentPage; + private String activeUuid; // Pagination buttons private Button firstPageButton; @@ -213,4 +214,11 @@ public boolean isEmpty() { return entries.isEmpty(); } + public String getActiveUuid() { + return activeUuid; + } + + public void setActiveUuid(String activeUuid) { + this.activeUuid = activeUuid; + } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/components/sidecomponent/SideComponentField.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/components/sidecomponent/SideComponentField.java index 4c7828b5e9b..d0a3bfe1c67 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/components/sidecomponent/SideComponentField.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/components/sidecomponent/SideComponentField.java @@ -83,4 +83,8 @@ public void addDeleteButton(String id, Button.ClickListener actionClickListener) setComponentAlignment(actionButton, Alignment.TOP_RIGHT); setExpandRatio(actionButton, 0); } + + public void setActive() { + mainLayout.addStyleName(CssStyles.ACTIVE_SIDE_COMPONENT_ELEMENT); + } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/vaccination/list/VaccinationList.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/vaccination/list/VaccinationList.java index 81e01fde569..d6e966acdd2 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/vaccination/list/VaccinationList.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/vaccination/list/VaccinationList.java @@ -74,20 +74,26 @@ protected void drawDisplayedEntries() { boolean isEditableAndHasEditRight = isEditAllowed && UserProvider.getCurrent().hasUserRight(UserRight.IMMUNIZATION_EDIT); for (VaccinationListEntryDto entryDto : getDisplayedEntries()) { VaccinationListEntry listEntry = new VaccinationListEntry(entryDto, disease == null); - listEntry.addActionButton(listEntry.getVaccination().getUuid(), e -> actionCallback.accept(() -> { - VaccinationListEntryDto vaccination = listEntry.getVaccination(); - ControllerProvider.getVaccinationController() - .edit( - FacadeProvider.getVaccinationFacade().getByUuid(listEntry.getVaccination().getUuid()), - listEntry.getVaccination().getDisease(), - UiFieldAccessCheckers.forDataAccessLevel( - UserProvider.getCurrent().getPseudonymizableDataAccessLevel(vaccination.isInJurisdiction()), - vaccination.isPseudonymized()), - true, - v -> SormasUI.refreshView(), - deleteCallback(), - isEditableAndHasEditRight); - }), isEditableAndHasEditRight); + boolean isActiveVaccination = entryDto.getUuid().equals(getActiveUuid()); + if (isActiveVaccination) { + listEntry.setActive(); + } + if (!isActiveVaccination) { + listEntry.addActionButton(listEntry.getVaccination().getUuid(), e -> actionCallback.accept(() -> { + VaccinationListEntryDto vaccination = listEntry.getVaccination(); + ControllerProvider.getVaccinationController() + .edit( + FacadeProvider.getVaccinationFacade().getByUuid(listEntry.getVaccination().getUuid()), + listEntry.getVaccination().getDisease(), + UiFieldAccessCheckers.forDataAccessLevel( + UserProvider.getCurrent().getPseudonymizableDataAccessLevel(vaccination.isInJurisdiction()), + vaccination.isPseudonymized()), + true, + v -> SormasUI.refreshView(), + deleteCallback(), + isEditableAndHasEditRight); + }), isEditableAndHasEditRight); + } listEntry.setEnabled(isEditAllowed && entryDto.isRelevant()); listLayout.addComponent(listEntry); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/vaccination/list/VaccinationListComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/vaccination/list/VaccinationListComponent.java index 042d399bce3..ec45d89f4e0 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/vaccination/list/VaccinationListComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/vaccination/list/VaccinationListComponent.java @@ -34,12 +34,17 @@ public class VaccinationListComponent extends SideComponent { - public VaccinationListComponent(Supplier criteriaSupplier, Consumer actionCallback, boolean isEditAllowed) { - this(criteriaSupplier, actionCallback, true, isEditAllowed); + public VaccinationListComponent( + Supplier criteriaSupplier, + String activeUuid, + Consumer actionCallback, + boolean isEditAllowed) { + this(criteriaSupplier, activeUuid, actionCallback, true, isEditAllowed); } public VaccinationListComponent( Supplier criteriaSupplier, + String activeUuid, Consumer actionCallback, boolean allowNewVaccine, boolean isEditAllowed) { @@ -85,6 +90,7 @@ public VaccinationListComponent( } VaccinationList vaccinationList = new VaccinationList(criteria.getDisease(), entriesListSupplier, actionCallback, isEditAllowed); + vaccinationList.setActiveUuid(activeUuid); addComponent(vaccinationList); vaccinationList.reload(); } diff --git a/sormas-ui/src/main/webapp/VAADIN/themes/sormas/global.scss b/sormas-ui/src/main/webapp/VAADIN/themes/sormas/global.scss index 3f815ab3d02..7bbb350e92b 100644 --- a/sormas-ui/src/main/webapp/VAADIN/themes/sormas/global.scss +++ b/sormas-ui/src/main/webapp/VAADIN/themes/sormas/global.scss @@ -331,6 +331,11 @@ padding: 12px 20px; margin-bottom: 24px; } + .active-side-component-element { + background-color: $v-focus-color; + border-radius: 6px; + padding: 6px; + } .spacing-small { .v-spacing { From 8d34308e9831c092b05f882c54f74532e1ca0a34 Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Tue, 13 Dec 2022 17:05:00 +0200 Subject: [PATCH 011/166] #8465 - Display soft-deleted entities to users that have the right to delete --- .../sormas/api/EntityRelevanceStatus.java | 9 +- .../symeda/sormas/api/caze/CaseCriteria.java | 11 --- .../sormas/api/caze/CaseIndexDetailedDto.java | 11 ++- .../symeda/sormas/api/caze/CaseIndexDto.java | 32 +++++- .../sormas/api/contact/ContactCriteria.java | 11 --- .../api/contact/ContactIndexDetailedDto.java | 5 +- .../sormas/api/contact/ContactIndexDto.java | 25 ++++- .../sormas/api/event/EventActionIndexDto.java | 25 ++++- .../sormas/api/event/EventIndexDto.java | 26 ++++- .../api/event/EventParticipantIndexDto.java | 24 +++++ .../de/symeda/sormas/api/i18n/Captions.java | 22 +++-- .../immunization/ImmunizationCriteria.java | 10 ++ .../immunization/ImmunizationIndexDto.java | 23 +++++ .../sormas/api/sample/SampleCriteria.java | 11 --- .../sormas/api/sample/SampleIndexDto.java | 26 ++++- .../api/travelentry/TravelEntryCriteria.java | 13 +-- .../api/travelentry/TravelEntryIndexDto.java | 24 +++++ .../src/main/resources/captions.properties | 22 +++-- .../sormas/backend/action/ActionService.java | 5 +- ...EventActionIndexDtoReasultTransformer.java | 5 +- .../backend/caze/CaseListCriteriaBuilder.java | 2 + .../sormas/backend/caze/CaseService.java | 7 +- .../contact/ContactListCriteriaBuilder.java | 2 + .../backend/contact/ContactService.java | 8 +- .../sormas/backend/event/EventFacadeEjb.java | 4 +- .../event/EventParticipantFacadeEjb.java | 4 + .../event/EventParticipantService.java | 7 +- .../sormas/backend/event/EventService.java | 9 +- .../DirectoryImmunizationService.java | 18 +++- ...ImmunizationIndexDtoResultTransformer.java | 5 +- .../sormas/backend/sample/SampleService.java | 10 +- .../services/TravelEntryService.java | 13 +-- .../TravelEntryIndexDtoResultTransformer.java | 5 +- .../event/EventParticipantFacadeEjbTest.java | 4 +- .../backend/task/TaskFacadeEjbTest.java | 3 +- .../ui/campaign/campaigns/CampaignsView.java | 3 +- .../sormas/ui/caze/AbstractCaseGrid.java | 18 +++- .../de/symeda/sormas/ui/caze/CasesView.java | 11 ++- .../infrastructure/AreasView.java | 48 +++++---- .../infrastructure/CommunitiesView.java | 5 +- .../infrastructure/ContinentsView.java | 5 +- .../infrastructure/CountriesView.java | 5 +- .../infrastructure/DistrictsView.java | 5 +- .../infrastructure/FacilitiesView.java | 9 +- .../infrastructure/PointsOfEntryView.java | 16 +-- .../infrastructure/RegionsView.java | 4 +- .../infrastructure/SubcontinentsView.java | 5 +- .../ui/contact/AbstractContactGrid.java | 18 +++- .../sormas/ui/contact/ContactsView.java | 13 ++- .../sormas/ui/events/EventActionsGrid.java | 22 ++++- .../de/symeda/sormas/ui/events/EventGrid.java | 14 +++ .../ui/events/EventParticipantsGrid.java | 14 ++- .../ui/events/EventParticipantsView.java | 16 ++- .../symeda/sormas/ui/events/EventsView.java | 14 ++- .../ui/immunization/ImmunizationsView.java | 98 ++++++++++++++++++- .../components/grid/ImmunizationGrid.java | 16 ++- .../symeda/sormas/ui/samples/SampleGrid.java | 14 ++- .../ui/samples/SampleGridComponent.java | 12 ++- .../sormas/ui/task/TaskGridComponent.java | 4 +- .../ui/travelentry/TravelEntriesView.java | 45 +++++---- .../ui/travelentry/TravelEntryGrid.java | 18 +++- .../symeda/sormas/ui/utils/FilteredGrid.java | 3 +- 62 files changed, 704 insertions(+), 192 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/EntityRelevanceStatus.java b/sormas-api/src/main/java/de/symeda/sormas/api/EntityRelevanceStatus.java index 52f383d823b..4d7a95e9bab 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/EntityRelevanceStatus.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/EntityRelevanceStatus.java @@ -1,15 +1,22 @@ package de.symeda.sormas.api; +import java.util.Arrays; + import de.symeda.sormas.api.i18n.I18nProperties; public enum EntityRelevanceStatus { ACTIVE, ARCHIVED, - ALL; + ACTIVE_AND_ARCHIVED, + DELETED; @Override public String toString() { return I18nProperties.getEnumCaption(this); } + + public static Object[] getAllExceptDeleted() { + return Arrays.stream(EntityRelevanceStatus.values()).filter(val -> val != EntityRelevanceStatus.DELETED).toArray(); + }; } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseCriteria.java b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseCriteria.java index afb73828a54..e461ea9af3b 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseCriteria.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseCriteria.java @@ -115,7 +115,6 @@ public class CaseCriteria extends CriteriaWithDateType implements ExternalShareC private Boolean withExtendedQuarantine; private Boolean withReducedQuarantine; private Boolean onlyQuarantineHelpNeeded; - private Boolean deleted = Boolean.FALSE; private String caseLike; private String eventLike; private Boolean onlyCasesWithEvents = Boolean.FALSE; @@ -452,16 +451,6 @@ public EntityRelevanceStatus getRelevanceStatus() { return relevanceStatus; } - public CaseCriteria deleted(Boolean deleted) { - this.deleted = deleted; - return this; - } - - @IgnoreForUrl - public Boolean getDeleted() { - return deleted; - } - /** * returns all entries that match ALL of the passed words */ diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseIndexDetailedDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseIndexDetailedDto.java index c855c4f363b..05b63ea943d 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseIndexDetailedDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseIndexDetailedDto.java @@ -3,6 +3,7 @@ import java.util.Date; import de.symeda.sormas.api.Disease; +import de.symeda.sormas.api.common.DeletionReason; import de.symeda.sormas.api.contact.FollowUpStatus; import de.symeda.sormas.api.disease.DiseaseVariant; import de.symeda.sormas.api.event.EventStatus; @@ -81,7 +82,7 @@ public CaseIndexDetailedDto(long id, String uuid, String epidNumber, String exte String pointOfEntryUuid, String pointOfEntryName, String pointOfEntryDetails, String surveillanceOfficerUuid, CaseOutcome outcome, Integer age, ApproximateAgeType ageType, Integer birthdateDD, Integer birthdateMM, Integer birthdateYYYY, Sex sex, Date quarantineTo, Float completeness, FollowUpStatus followUpStatus, Date followUpUntil, SymptomJournalStatus symptomJournalStatus, VaccinationStatus vaccinationStatus, Date changeDate, Long facilityId, - String responsibleRegionUuid, String responsibleDistrictUuid, String responsibleDistrictName, boolean isInJurisdiction, + String responsibleRegionUuid, String responsibleDistrictUuid, String responsibleDistrictName, DeletionReason deletionReason, String otherDeleteReason, boolean isInJurisdiction, //detailed fields YesNoUnknown reInfection, String city, String street, String houseNumber, String additionalInformation, String postalCode, String phone, String reportingUserUuid, String reportingUserFirstName, String reportingUserLastName, Date symptomOnsetDate, @@ -94,7 +95,7 @@ public CaseIndexDetailedDto(long id, String uuid, String epidNumber, String exte healthFacilityName, healthFacilityDetails, pointOfEntryUuid, pointOfEntryName, pointOfEntryDetails, surveillanceOfficerUuid, outcome, age, ageType, birthdateDD, birthdateMM, birthdateYYYY, sex, quarantineTo, completeness, followUpStatus, followUpUntil, symptomJournalStatus, vaccinationStatus, changeDate, facilityId, - responsibleRegionUuid, responsibleDistrictUuid, responsibleDistrictName, isInJurisdiction, visitCount, latestChangedDate); + responsibleRegionUuid, responsibleDistrictUuid, responsibleDistrictName, deletionReason, otherDeleteReason, isInJurisdiction, visitCount, latestChangedDate); //@formatter:on this.reInfection = reInfection; @@ -113,6 +114,7 @@ public CaseIndexDetailedDto(long id, String uuid, String epidNumber, String exte this.responsibleCommunity = responsibleCommunity; } + //@formatter:off public CaseIndexDetailedDto( long id, String uuid, String epidNumber, String externalID, String externalToken, String internalToken, String personUuid, String personFirstName, String personLastName, @@ -125,7 +127,7 @@ public CaseIndexDetailedDto( CaseOutcome outcome, Integer age, ApproximateAgeType ageType, Integer birthdateDD, Integer birthdateMM, Integer birthdateYYYY, Sex sex, Date quarantineTo, Float completeness, FollowUpStatus followUpStatus, Date followUpUntil, SymptomJournalStatus symptomJournalStatus, VaccinationStatus vaccinationStatus, Date changeDate, Long facilityId, - String responsibleRegionUuid, String responsibleDistrictUuid, String responsibleDistrictName, boolean isInJurisdiction, + String responsibleRegionUuid, String responsibleDistrictUuid, String responsibleDistrictName, DeletionReason deletionReason, String otherDeleteReason, boolean isInJurisdiction, //detailed fields YesNoUnknown reInfection, String city, String street, String houseNumber, String additionalInformation, String postalCode, String phone, String reportingUserUuid, String reportingUserFirstName, String reportingUserLastName, @@ -137,10 +139,11 @@ public CaseIndexDetailedDto( healthFacilityDetails, pointOfEntryUuid, pointOfEntryName, pointOfEntryDetails, surveillanceOfficerUuid, outcome, age, ageType, birthdateDD, birthdateMM, birthdateYYYY, sex, quarantineTo, completeness, followUpStatus, followUpUntil, symptomJournalStatus, vaccinationStatus, changeDate, facilityId, - responsibleRegionUuid, responsibleDistrictUuid, responsibleDistrictName, isInJurisdiction, reInfection, + responsibleRegionUuid, responsibleDistrictUuid, responsibleDistrictName, deletionReason, otherDeleteReason, isInJurisdiction, reInfection, city, street, houseNumber, additionalInformation, postalCode, phone, reportingUserUuid, reportingUserFirstName, reportingUserLastName, symptomOnsetDate, responsibleRegion, responsibleCommunity, visitCount, 0, latestSampleDateTime, sampleCount, latestChangedDate); + //@formatter:on } public YesNoUnknown getReInfection() { diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseIndexDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseIndexDto.java index e81156be922..d81e482a300 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseIndexDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseIndexDto.java @@ -22,6 +22,7 @@ import de.symeda.sormas.api.Disease; import de.symeda.sormas.api.MergeableIndexDto; +import de.symeda.sormas.api.common.DeletionReason; import de.symeda.sormas.api.contact.FollowUpStatus; import de.symeda.sormas.api.disease.DiseaseVariant; import de.symeda.sormas.api.infrastructure.InfrastructureHelper; @@ -34,8 +35,6 @@ import de.symeda.sormas.api.utils.PersonalData; import de.symeda.sormas.api.utils.SensitiveData; import de.symeda.sormas.api.utils.pseudonymization.PseudonymizableIndexDto; -import de.symeda.sormas.api.vaccination.VaccinationDto; -import org.apache.commons.lang3.StringUtils; public class CaseIndexDto extends PseudonymizableIndexDto implements MergeableIndexDto, Serializable, Cloneable { @@ -61,6 +60,7 @@ public class CaseIndexDto extends PseudonymizableIndexDto implements MergeableIn public static final String REPORT_DATE = "reportDate"; public static final String CREATION_DATE = "creationDate"; public static final String REGION_UUID = "regionUuid"; + public static final String DELETE_REASON = "deletionReason"; public static final String DISTRICT_UUID = "districtUuid"; public static final String RESPONSIBLE_DISTRICT_NAME = "responsibleDistrictName"; public static final String HEALTH_FACILITY_UUID = "healthFacilityUuid"; @@ -128,6 +128,9 @@ public class CaseIndexDto extends PseudonymizableIndexDto implements MergeableIn private String districtUuid; private String responsibleDistrictName; + private DeletionReason deletionReason; + private String otherDeletionReason; + private Boolean isInJurisdiction; //@formatter:off @@ -139,7 +142,7 @@ public CaseIndexDto(long id, String uuid, String epidNumber, String externalID, Integer age, ApproximateAgeType ageType, Integer birthdateDD, Integer birthdateMM, Integer birthdateYYYY, Sex sex, Date quarantineTo, Float completeness, FollowUpStatus followUpStatus, Date followUpUntil, SymptomJournalStatus symptomJournalStatus, VaccinationStatus vaccinationStatus, Date changeDate, Long facilityId, // responsible jurisdiction - String responsibleRegionUuid, String responsibleDistrictUuid, String responsibleDistrictName, boolean isInJurisdiction) { + String responsibleRegionUuid, String responsibleDistrictUuid, String responsibleDistrictName, DeletionReason deletionReason, String otherDeletionReason, boolean isInJurisdiction) { this(id, uuid, epidNumber, externalID, externalToken, internalToken, personUuid, personFirstName, personLastName, disease, diseaseVariant, diseaseDetails, caseClassification, investigationStatus, presentCondition, reportDate, creationDate, regionUuid, @@ -147,7 +150,7 @@ public CaseIndexDto(long id, String uuid, String epidNumber, String externalID, pointOfEntryUuid, pointOfEntryName, pointOfEntryDetails, surveillanceOfficerUuid, outcome, age, ageType, birthdateDD, birthdateMM, birthdateYYYY, sex, quarantineTo, completeness, followUpStatus, followUpUntil, symptomJournalStatus, vaccinationStatus, changeDate, facilityId, - responsibleRegionUuid, responsibleDistrictUuid, responsibleDistrictName, isInJurisdiction, + responsibleRegionUuid, responsibleDistrictUuid, responsibleDistrictName, deletionReason, otherDeletionReason, isInJurisdiction, null, null ); } @@ -163,7 +166,7 @@ public CaseIndexDto(long id, String uuid, String epidNumber, String externalID, Float completeness, FollowUpStatus followUpStatus, Date followUpUntil, SymptomJournalStatus symptomJournalStatus, VaccinationStatus vaccinationStatus, Date changeDate, Long facilityId, // XXX: unused, only here for TypedQuery mapping // responsible jurisdiction - String responsibleRegionUuid, String responsibleDistrictUuid, String responsibleDistrictName, boolean isInJurisdiction, + String responsibleRegionUuid, String responsibleDistrictUuid, String responsibleDistrictName, DeletionReason deletionReason, String otherDeletionReason, boolean isInJurisdiction, // others Integer visitCount, Date latestChangedDate // unused, only here for TypedQuery mapping @@ -208,6 +211,9 @@ public CaseIndexDto(long id, String uuid, String epidNumber, String externalID, this.districtUuid = districtUuid; this.regionUuid = regionUuid; + this.deletionReason = deletionReason; + this.otherDeletionReason = otherDeletionReason; + this.isInJurisdiction = isInJurisdiction; } @@ -437,6 +443,22 @@ public Boolean getInJurisdiction() { return isInJurisdiction; } + public DeletionReason getDeletionReason() { + return deletionReason; + } + + public void setDeletionReason(DeletionReason deletionReason) { + this.deletionReason = deletionReason; + } + + public String getOtherDeletionReason() { + return otherDeletionReason; + } + + public void setOtherDeletionReason(String otherDeletionReason) { + this.otherDeletionReason = otherDeletionReason; + } + public FollowUpStatus getFollowUpStatus() { return followUpStatus; } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactCriteria.java b/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactCriteria.java index ac211579b1c..62f33686e50 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactCriteria.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactCriteria.java @@ -107,7 +107,6 @@ public class ContactCriteria extends BaseCriteria implements Serializable { private ContactRelation relationToCase; private Date lastContactDateFrom; private Date lastContactDateTo; - private Boolean deleted = Boolean.FALSE; private String contactOrCaseLike; private EntityRelevanceStatus relevanceStatus; private Boolean onlyHighPriorityContacts; @@ -391,16 +390,6 @@ public EntityRelevanceStatus getRelevanceStatus() { return relevanceStatus; } - public ContactCriteria deleted(Boolean deleted) { - this.deleted = deleted; - return this; - } - - @IgnoreForUrl - public Boolean getDeleted() { - return deleted; - } - /** * returns all entries that match ALL of the passed words */ diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactIndexDetailedDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactIndexDetailedDto.java index 79b0715d8c0..9526c22ca08 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactIndexDetailedDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactIndexDetailedDto.java @@ -5,6 +5,7 @@ import de.symeda.sormas.api.Disease; import de.symeda.sormas.api.caze.CaseClassification; import de.symeda.sormas.api.caze.VaccinationStatus; +import de.symeda.sormas.api.common.DeletionReason; import de.symeda.sormas.api.person.ApproximateAgeType; import de.symeda.sormas.api.person.Sex; import de.symeda.sormas.api.person.SymptomJournalStatus; @@ -69,7 +70,7 @@ public ContactIndexDetailedDto(String uuid, String personUuid, String personFirs String caseRegionName, String caseDistrictName, Date changeDate, // XXX: unused, only here for TypedQuery mapping - String externalID, String externalToken, String internalToken, boolean isInJurisdiction, boolean isCaseInJurisdiction, + String externalID, String externalToken, String internalToken, DeletionReason deletionReason, String otherDeleteReason, boolean isInJurisdiction, boolean isCaseInJurisdiction, Sex sex, Integer approximateAge, ApproximateAgeType approximateAgeType, String city, String street, String houseNumber, String additionalInformation, String postalCode, String phone, String reportingUserFirstName, String reportingUserLastName, ContactRelation relationToCase, int visitCount, @@ -81,7 +82,7 @@ public ContactIndexDetailedDto(String uuid, String personUuid, String personFirs super(uuid, personUuid, personFirstName, personLastName, cazeUuid, disease, diseaseDetails, caseFirstName, caseLastName, regionName, districtName, lastContactDate, contactCategory, contactProximity, contactClassification, contactStatus, completeness, followUpStatus, followUpUntil, symptomJournalStatus, vaccinationStatus, contactOfficerUuid, reportingUserUuid, reportDateTime, caseClassification, - caseRegionName, caseDistrictName, changeDate, externalID, externalToken, internalToken, isInJurisdiction, isCaseInJurisdiction , visitCount, latestChangedDate); + caseRegionName, caseDistrictName, changeDate, externalID, externalToken, internalToken, deletionReason, otherDeleteReason,isInJurisdiction, isCaseInJurisdiction , visitCount, latestChangedDate); //@formatter:on diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactIndexDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactIndexDto.java index 4ec60458def..a5a98148e38 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactIndexDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactIndexDto.java @@ -24,6 +24,7 @@ import de.symeda.sormas.api.caze.CaseClassification; import de.symeda.sormas.api.caze.CaseReferenceDto; import de.symeda.sormas.api.caze.VaccinationStatus; +import de.symeda.sormas.api.common.DeletionReason; import de.symeda.sormas.api.person.SymptomJournalStatus; import de.symeda.sormas.api.utils.PersonalData; import de.symeda.sormas.api.utils.pseudonymization.PseudonymizableIndexDto; @@ -91,6 +92,9 @@ public class ContactIndexDto extends PseudonymizableIndexDto implements Serializ private String caseRegionName; private String caseDistrictName; + private DeletionReason deletionReason; + private String otherDeletionReason; + private ContactJurisdictionFlagsDto contactJurisdictionFlagsDto; //@formatter:off @@ -102,7 +106,7 @@ public ContactIndexDto(String uuid, String personUuid, String personFirstName, S String reportingUserUuid, Date reportDateTime, CaseClassification caseClassification, String caseRegionName, String caseDistrictName, Date changeDate, // XXX: unused, only here for TypedQuery mapping - String externalID, String externalToken, String internalToken, boolean isInJurisdiction, boolean isCaseInJurisdiction, + String externalID, String externalToken, String internalToken, DeletionReason deletionReason, String otherDeletionReason, boolean isInJurisdiction, boolean isCaseInJurisdiction, int visitCount, Date latestChangedDate // unused, only here for TypedQuery mapping ) { @@ -141,6 +145,9 @@ public ContactIndexDto(String uuid, String personUuid, String personFirstName, S this.caseRegionName = caseRegionName; this.caseDistrictName = caseDistrictName; + this.deletionReason = deletionReason; + this.otherDeletionReason = otherDeletionReason; + this.contactJurisdictionFlagsDto = new ContactJurisdictionFlagsDto(isInJurisdiction, isCaseInJurisdiction); } @@ -376,6 +383,22 @@ public boolean getCaseInJurisdiction() { return contactJurisdictionFlagsDto.getCaseInJurisdiction(); } + public DeletionReason getDeletionReason() { + return deletionReason; + } + + public void setDeletionReason(DeletionReason deletionReason) { + this.deletionReason = deletionReason; + } + + public String getOtherDeletionReason() { + return otherDeletionReason; + } + + public void setOtherDeletionReason(String otherDeletionReason) { + this.otherDeletionReason = otherDeletionReason; + } + @Override public Object clone() throws CloneNotSupportedException { return super.clone(); diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/event/EventActionIndexDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/event/EventActionIndexDto.java index e9b80ef3378..0250bb7708f 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/event/EventActionIndexDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/event/EventActionIndexDto.java @@ -23,6 +23,7 @@ import de.symeda.sormas.api.Disease; import de.symeda.sormas.api.action.ActionPriority; import de.symeda.sormas.api.action.ActionStatus; +import de.symeda.sormas.api.common.DeletionReason; import de.symeda.sormas.api.disease.DiseaseVariant; import de.symeda.sormas.api.user.UserReferenceDto; @@ -79,6 +80,8 @@ public class EventActionIndexDto implements Serializable { private ActionPriority actionPriority; private UserReferenceDto actionLastModifiedBy; private UserReferenceDto actionCreatorUser; + private DeletionReason deletionReason; + private String otherDeletionReason; public EventActionIndexDto( String eventUuid, @@ -103,7 +106,9 @@ public EventActionIndexDto( ActionStatus actionStatus, ActionPriority actionPriority, UserReferenceDto actionLastModifiedBy, - UserReferenceDto actionCreatorUser) { + UserReferenceDto actionCreatorUser, + DeletionReason deletionReason, + String otherDeletionReason) { this.eventUuid = eventUuid; this.eventTitle = eventTitle; @@ -128,6 +133,8 @@ public EventActionIndexDto( this.actionPriority = actionPriority; this.actionLastModifiedBy = actionLastModifiedBy; this.actionCreatorUser = actionCreatorUser; + this.deletionReason = deletionReason; + this.otherDeletionReason = otherDeletionReason; } public String getEventUuid() { @@ -313,4 +320,20 @@ public EventManagementStatus getEventManagementStatus() { public void setEventManagementStatus(EventManagementStatus eventManagementStatus) { this.eventManagementStatus = eventManagementStatus; } + + public DeletionReason getDeletionReason() { + return deletionReason; + } + + public void setDeletionReason(DeletionReason deletionReason) { + this.deletionReason = deletionReason; + } + + public String getOtherDeletionReason() { + return otherDeletionReason; + } + + public void setOtherDeletionReason(String otherDeletionReason) { + this.otherDeletionReason = otherDeletionReason; + } } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/event/EventIndexDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/event/EventIndexDto.java index 63e1967f1d5..c6f38a67f71 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/event/EventIndexDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/event/EventIndexDto.java @@ -19,6 +19,7 @@ import java.util.Date; import de.symeda.sormas.api.Disease; +import de.symeda.sormas.api.common.DeletionReason; import de.symeda.sormas.api.disease.DiseaseVariant; import de.symeda.sormas.api.location.LocationReferenceDto; import de.symeda.sormas.api.share.ExternalShareStatus; @@ -116,6 +117,9 @@ public class EventIndexDto extends PseudonymizableIndexDto { private Long surveillanceToolShareCount; private ExternalShareStatus surveillanceToolStatus; + private DeletionReason deletionReason; + private String otherDeletionReason; + public EventIndexDto( Long id, String uuid, @@ -159,7 +163,9 @@ public EventIndexDto( String responsibleUserLastName, boolean isInJurisdictionOrOwned, Date changeDate, - EventIdentificationSource eventIdentificationSource) { + EventIdentificationSource eventIdentificationSource, + DeletionReason deletionReason, + String otherDeletionReason) { super(uuid); this.id = id; @@ -191,6 +197,8 @@ public EventIndexDto( this.isInJurisdictionOrOwned = isInJurisdictionOrOwned; this.regionUuid = regionUuid; this.eventIdentificationSource = eventIdentificationSource; + this.deletionReason = deletionReason; + this.otherDeletionReason = otherDeletionReason; } public EventIndexDto(String uuid) { @@ -497,6 +505,22 @@ public void setEventIdentificationSource(EventIdentificationSource eventIdentifi this.eventIdentificationSource = eventIdentificationSource; } + public DeletionReason getDeletionReason() { + return deletionReason; + } + + public void setDeletionReason(DeletionReason deletionReason) { + this.deletionReason = deletionReason; + } + + public String getOtherDeletionReason() { + return otherDeletionReason; + } + + public void setOtherDeletionReason(String otherDeletionReason) { + this.otherDeletionReason = otherDeletionReason; + } + public EventReferenceDto toReference() { return new EventReferenceDto(getUuid(), getDisease(), getDiseaseDetails(), getEventStatus(), getEventInvestigationStatus(), getStartDate()); } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/event/EventParticipantIndexDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/event/EventParticipantIndexDto.java index 6bb55d23465..d40b73a7ec2 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/event/EventParticipantIndexDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/event/EventParticipantIndexDto.java @@ -4,6 +4,7 @@ import java.util.Date; import de.symeda.sormas.api.caze.VaccinationStatus; +import de.symeda.sormas.api.common.DeletionReason; import de.symeda.sormas.api.person.ApproximateAgeType; import de.symeda.sormas.api.person.Sex; import de.symeda.sormas.api.sample.PathogenTestResultType; @@ -48,6 +49,9 @@ public class EventParticipantIndexDto extends PseudonymizableIndexDto implements private VaccinationStatus vaccinationStatus; + private DeletionReason deletionReason; + private String otherDeletionReason; + private boolean isInJurisdiction; private boolean isInJurisdictionOrOwned; @@ -66,6 +70,8 @@ public EventParticipantIndexDto( Date sampleDateTime, VaccinationStatus vaccinationStatus, String reportingUserUuid, + DeletionReason deletionReason, + String otherDeletionReason, boolean isInJurisdiction, boolean isInJurisdictionOrOwned) { @@ -81,6 +87,8 @@ public EventParticipantIndexDto( this.pathogenTestResult = pathogenTestResult; this.sampleDateTime = sampleDateTime; this.vaccinationStatus = vaccinationStatus; + this.deletionReason = deletionReason; + this.otherDeletionReason = otherDeletionReason; this.isInJurisdiction = isInJurisdiction; this.isInJurisdictionOrOwned = isInJurisdictionOrOwned; } @@ -192,4 +200,20 @@ public boolean getInJurisdictionOrOwned() { public EventParticipantReferenceDto toReference() { return new EventParticipantReferenceDto(getUuid(), firstName, lastName); } + + public DeletionReason getDeletionReason() { + return deletionReason; + } + + public void setDeletionReason(DeletionReason deletionReason) { + this.deletionReason = deletionReason; + } + + public String getOtherDeletionReason() { + return otherDeletionReason; + } + + public void setOtherDeletionReason(String otherDeletionReason) { + this.otherDeletionReason = otherDeletionReason; + } } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java index ebd9fed7f5b..79f276e63d4 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java @@ -276,7 +276,8 @@ public interface Captions { String cancelExternalFollowUpPopupTitle = "cancelExternalFollowUpPopupTitle"; String captionDefault = "captionDefault"; String caseActiveCases = "caseActiveCases"; - String caseAllCases = "caseAllCases"; + String caseAllActiveAndArchivedCases = "caseAllActiveAndArchivedCases"; + String caseDeletedCases = "caseDeletedCases"; String caseArchivedCases = "caseArchivedCases"; String caseBackToDirectory = "caseBackToDirectory"; String caseCalculateCompleteness = "caseCalculateCompleteness"; @@ -715,7 +716,7 @@ public interface Captions { String Contact_vaccinationStatus = "Contact.vaccinationStatus"; String Contact_visits = "Contact.visits"; String contactActiveContacts = "contactActiveContacts"; - String contactAllContacts = "contactAllContacts"; + String contactAllActiveAndArchiveContacts = "contactAllActiveAndArchiveContacts"; String contactArchivedContacts = "contactArchivedContacts"; String contactBackToDirectory = "contactBackToDirectory"; String contactCalculateCompleteness = "contactCalculateCompleteness"; @@ -729,6 +730,7 @@ public interface Captions { String contactCreateContactCase = "contactCreateContactCase"; String contactCreateNew = "contactCreateNew"; String contactDetailedOverview = "contactDetailedOverview"; + String contactDeletedContacts = "contactDeletedContacts"; String ContactExport_address = "ContactExport.address"; String ContactExport_addressCommunity = "ContactExport.addressCommunity"; String ContactExport_addressDistrict = "ContactExport.addressDistrict"; @@ -1142,10 +1144,11 @@ public interface Captions { String eventActionsView = "eventActionsView"; String eventActiveEvents = "eventActiveEvents"; String eventActiveGroups = "eventActiveGroups"; - String eventAllEvents = "eventAllEvents"; + String eventAllActiveAndArchivedEvents = "eventAllActiveAndArchivedEvents"; String eventAllGroups = "eventAllGroups"; String eventArchivedEvents = "eventArchivedEvents"; String eventArchivedGroups = "eventArchivedGroups"; + String eventDeletedEvents = "eventDeletedEvents"; String eventDefaultView = "eventDefaultView"; String eventEditEvent = "eventEditEvent"; String eventEditEventGroup = "eventEditEventGroup"; @@ -1198,10 +1201,11 @@ public interface Captions { String EventParticipant_vaccinationStatus = "EventParticipant.vaccinationStatus"; String eventParticipantActiveEventParticipants = "eventParticipantActiveEventParticipants"; String eventParticipantAddPerson = "eventParticipantAddPerson"; - String eventParticipantAllEventParticipants = "eventParticipantAllEventParticipants"; + String eventParticipantActiveAndArchivedEventParticipants = "eventParticipantActiveAndArchivedEventParticipants"; String eventParticipantArchivedEventParticipants = "eventParticipantArchivedEventParticipants"; String eventParticipantContactCountOnlyWithSourceCaseInEvent = "eventParticipantContactCountOnlyWithSourceCaseInEvent"; String eventParticipantCreateNew = "eventParticipantCreateNew"; + String eventParticipantDeletedEventParticipants = "eventParticipantDeletedEventParticipants"; String EventParticipantExport_addressCommunity = "EventParticipantExport.addressCommunity"; String EventParticipantExport_addressDistrict = "EventParticipantExport.addressDistrict"; String EventParticipantExport_addressGpsCoordinates = "EventParticipantExport.addressGpsCoordinates"; @@ -1471,6 +1475,10 @@ public interface Captions { String Immunization_vaccinations = "Immunization.vaccinations"; String Immunization_validFrom = "Immunization.validFrom"; String Immunization_validUntil = "Immunization.validUntil"; + String immunizationActiveImmunizations = "immunizationActiveImmunizations"; + String immunizationArchivedImmunizations = "immunizationArchivedImmunizations"; + String immunizationAllActiveAndArchivedImmunizations = "immunizationAllActiveAndArchivedImmunizations"; + String immunizationDeletedImmunizations = "immunizationDeletedImmunizations"; String immunizationCreateNewImmunization = "immunizationCreateNewImmunization"; String immunizationImmunizationsList = "immunizationImmunizationsList"; String immunizationKeepImmunization = "immunizationKeepImmunization"; @@ -1902,10 +1910,11 @@ public interface Captions { String Sample_typeOfTest = "Sample.typeOfTest"; String Sample_uuid = "Sample.uuid"; String sampleActiveSamples = "sampleActiveSamples"; - String sampleAllSamples = "sampleAllSamples"; + String sampleAllActiveAndArchivedSamples = "sampleAllActiveAndArchivedSamples"; String sampleArchivedSamples = "sampleArchivedSamples"; String sampleAssociationType = "sampleAssociationType"; String sampleCreateNew = "sampleCreateNew"; + String sampleDeletedSamples = "sampleDeletedSamples"; String SampleExport_additionalTestingRequested = "SampleExport.additionalTestingRequested"; String SampleExport_altSgpt = "SampleExport.altSgpt"; String SampleExport_arterialVenousBloodGas = "SampleExport.arterialVenousBloodGas"; @@ -2353,6 +2362,7 @@ public interface Captions { String TravelEntry_creationDate = "TravelEntry.creationDate"; String TravelEntry_dateOfArrival = "TravelEntry.dateOfArrival"; String TravelEntry_deletionReason = "TravelEntry.deletionReason"; + String TravelEntry_deletedTravelEntries = "TravelEntry.deletedTravelEntries"; String TravelEntry_differentPointOfEntryJurisdiction = "TravelEntry.differentPointOfEntryJurisdiction"; String TravelEntry_diseaseVariant = "TravelEntry.diseaseVariant"; String TravelEntry_externalId = "TravelEntry.externalId"; @@ -2392,7 +2402,7 @@ public interface Captions { String TravelEntry_uuid = "TravelEntry.uuid"; String TravelEntry_vaccinated = "TravelEntry.vaccinated"; String travelEntryActiveTravelEntries = "travelEntryActiveTravelEntries"; - String travelEntryAllTravelEntries = "travelEntryAllTravelEntries"; + String travelEntryAllActiveAndArchivedTravelEntries = "travelEntryAllActiveAndArchivedTravelEntries"; String travelEntryArchivedTravelEntries = "travelEntryArchivedTravelEntries"; String travelEntryCreateCase = "travelEntryCreateCase"; String travelEntryNewTravelEntry = "travelEntryNewTravelEntry"; diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/immunization/ImmunizationCriteria.java b/sormas-api/src/main/java/de/symeda/sormas/api/immunization/ImmunizationCriteria.java index b71a9085e85..047ef6664d7 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/immunization/ImmunizationCriteria.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/immunization/ImmunizationCriteria.java @@ -19,6 +19,7 @@ import java.util.Date; import de.symeda.sormas.api.Disease; +import de.symeda.sormas.api.EntityRelevanceStatus; import de.symeda.sormas.api.caze.CaseReferenceDto; import de.symeda.sormas.api.infrastructure.community.CommunityReferenceDto; import de.symeda.sormas.api.infrastructure.district.DistrictReferenceDto; @@ -72,6 +73,7 @@ public class ImmunizationCriteria extends BaseCriteria implements Serializable, private Date toDate; private CaseReferenceDto relatedCase; private PersonReferenceDto person; + private EntityRelevanceStatus relevanceStatus; public Disease getDisease() { return disease; @@ -250,4 +252,12 @@ public ImmunizationCriteria person(PersonReferenceDto person) { this.person = person; return this; } + + public EntityRelevanceStatus getRelevanceStatus() { + return relevanceStatus; + } + + public void relevanceStatus(EntityRelevanceStatus relevanceStatus) { + this.relevanceStatus = relevanceStatus; + } } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/immunization/ImmunizationIndexDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/immunization/ImmunizationIndexDto.java index 7d015400865..c4cd33c703a 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/immunization/ImmunizationIndexDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/immunization/ImmunizationIndexDto.java @@ -20,6 +20,7 @@ import de.symeda.sormas.api.Disease; import de.symeda.sormas.api.caze.AgeAndBirthDateDto; +import de.symeda.sormas.api.common.DeletionReason; import de.symeda.sormas.api.person.Sex; import de.symeda.sormas.api.utils.PersonalData; import de.symeda.sormas.api.utils.SensitiveData; @@ -64,6 +65,8 @@ public class ImmunizationIndexDto extends PseudonymizableIndexDto implements Ser private Date endDate; private String lastVaccineType; private Date recoveryDate; + private DeletionReason deletionReason; + private String otherDeletionReason; private boolean isInJurisdiction; @@ -83,6 +86,8 @@ public ImmunizationIndexDto( Date endDate, String lastVaccineType, Date recoveryDate, + DeletionReason deletionReason, + String otherDeletionReason, boolean isInJurisdiction) { super(uuid); @@ -100,6 +105,8 @@ public ImmunizationIndexDto( this.endDate = endDate; this.lastVaccineType = lastVaccineType; this.recoveryDate = recoveryDate; + this.deletionReason = deletionReason; + this.otherDeletionReason = otherDeletionReason; this.isInJurisdiction = isInJurisdiction; } @@ -215,6 +222,22 @@ public void setRecoveryDate(Date recoveryDate) { this.recoveryDate = recoveryDate; } + public DeletionReason getDeletionReason() { + return deletionReason; + } + + public void setDeletionReason(DeletionReason deletionReason) { + this.deletionReason = deletionReason; + } + + public String getOtherDeletionReason() { + return otherDeletionReason; + } + + public void setOtherDeletionReason(String otherDeletionReason) { + this.otherDeletionReason = otherDeletionReason; + } + public boolean isInJurisdiction() { return isInJurisdiction; } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/sample/SampleCriteria.java b/sormas-api/src/main/java/de/symeda/sormas/api/sample/SampleCriteria.java index b27d97a04fe..583cae23dd7 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/sample/SampleCriteria.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/sample/SampleCriteria.java @@ -60,7 +60,6 @@ public class SampleCriteria extends BaseCriteria implements Serializable { private CaseReferenceDto caze; private ContactReferenceDto contact; private EventParticipantReferenceDto eventParticipant; - private Boolean deleted = Boolean.FALSE; private String caseCodeIdLike; private EntityRelevanceStatus relevanceStatus; private SampleAssociationType sampleAssociationType; @@ -249,16 +248,6 @@ public EntityRelevanceStatus getRelevanceStatus() { return relevanceStatus; } - public SampleCriteria deleted(Boolean deleted) { - this.deleted = deleted; - return this; - } - - @IgnoreForUrl - public Boolean getDeleted() { - return deleted; - } - /** * returns all entries that match ALL of the passed words */ diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/sample/SampleIndexDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/sample/SampleIndexDto.java index 9ef92bd6a55..17eb345be88 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/sample/SampleIndexDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/sample/SampleIndexDto.java @@ -22,18 +22,17 @@ import de.symeda.sormas.api.Disease; import de.symeda.sormas.api.caze.CaseReferenceDto; +import de.symeda.sormas.api.common.DeletionReason; import de.symeda.sormas.api.contact.ContactReferenceDto; import de.symeda.sormas.api.event.EventParticipantReferenceDto; import de.symeda.sormas.api.infrastructure.facility.FacilityHelper; import de.symeda.sormas.api.infrastructure.facility.FacilityReferenceDto; -import de.symeda.sormas.api.person.PersonDto; import de.symeda.sormas.api.utils.DateFormatHelper; import de.symeda.sormas.api.utils.EmbeddedPersonalData; import de.symeda.sormas.api.utils.EmbeddedSensitiveData; import de.symeda.sormas.api.utils.pseudonymization.PseudonymizableIndexDto; import de.symeda.sormas.api.utils.pseudonymization.Pseudonymizer; import de.symeda.sormas.api.utils.pseudonymization.valuepseudonymizers.EmptyValuePseudonymizer; -import org.apache.commons.lang3.StringUtils; public class SampleIndexDto extends PseudonymizableIndexDto implements Serializable { @@ -99,6 +98,8 @@ public class SampleIndexDto extends PseudonymizableIndexDto implements Serializa private Float lastTestCqValue; private SampleJurisdictionFlagsDto sampleJurisdictionFlagsDto; + private DeletionReason deletionReason; + private String otherDeletionReason; //@formatter:off public SampleIndexDto(String uuid, String epidNumber, String labSampleId, Date sampleDateTime, @@ -110,7 +111,7 @@ public SampleIndexDto(String uuid, String epidNumber, String labSampleId, Date s String associatedContactUuid, String associatedContactFirstName, String associatedContactLastName, String associatedEventParticipantUuid, String associatedEventParticipantFirstName, String associatedEventParticipantLastName, Disease disease, String diseaseDetails, PathogenTestResultType pathogenTestResult, Boolean additionalTestingRequested, Boolean additionalTestPerformed, - String districtName, String labUuid, Long pathogenTestCount, + String districtName, String labUuid, DeletionReason deletionReason, String otherDeletionReason, Long pathogenTestCount, boolean isInJurisdiction, boolean isCaseInJurisdiction, boolean isContactInJurisdiction, boolean isContactCaseInJurisdiction, boolean isEventParticipantInJurisdiction) { //@formatter:on @@ -155,6 +156,9 @@ public SampleIndexDto(String uuid, String epidNumber, String labSampleId, Date s this.typeOfLastTest = null; this.lastTestCqValue = null; + this.deletionReason = deletionReason; + this.otherDeletionReason = otherDeletionReason; + this.sampleJurisdictionFlagsDto = new SampleJurisdictionFlagsDto( isInJurisdiction, isCaseInJurisdiction, @@ -377,6 +381,22 @@ public void setLastTestCqValue(Float lastTestCqValue) { this.lastTestCqValue = lastTestCqValue; } + public DeletionReason getDeletionReason() { + return deletionReason; + } + + public void setDeletionReason(DeletionReason deletionReason) { + this.deletionReason = deletionReason; + } + + public String getOtherDeletionReason() { + return otherDeletionReason; + } + + public void setOtherDeletionReason(String otherDeletionReason) { + this.otherDeletionReason = otherDeletionReason; + } + public String getCaption() { StringBuilder sb = new StringBuilder(); sb.append(DateFormatHelper.formatLocalDateTime(sampleDateTime)).append(" - "); diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/travelentry/TravelEntryCriteria.java b/sormas-api/src/main/java/de/symeda/sormas/api/travelentry/TravelEntryCriteria.java index 7bed58bd2df..4a08a4f44bc 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/travelentry/TravelEntryCriteria.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/travelentry/TravelEntryCriteria.java @@ -24,7 +24,6 @@ public class TravelEntryCriteria extends BaseCriteria implements Serializable, C private Boolean onlyEntriesConvertedToCase = Boolean.FALSE; private PersonReferenceDto person; private CaseReferenceDto caze; - private Boolean deleted = Boolean.FALSE; private EntityRelevanceStatus relevanceStatus; private Date reportDateFrom; private Date reportDateTo; @@ -95,13 +94,6 @@ public TravelEntryCriteria caze(CaseReferenceDto caze) { this.caze = caze; return this; } - public Boolean getDeleted() { - return deleted; - } - - public void setDeleted(Boolean deleted) { - this.deleted = deleted; - } public EntityRelevanceStatus getRelevanceStatus() { return relevanceStatus; @@ -135,10 +127,7 @@ public void setDateFilterOption(DateFilterOption dateFilterOption) { this.dateFilterOption = dateFilterOption; } - public TravelEntryCriteria reportDateBetween( - Date reportDateFrom, - Date reportDateTo, - DateFilterOption dateFilterOption) { + public TravelEntryCriteria reportDateBetween(Date reportDateFrom, Date reportDateTo, DateFilterOption dateFilterOption) { this.reportDateFrom = reportDateFrom; this.reportDateTo = reportDateTo; this.dateFilterOption = dateFilterOption; diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/travelentry/TravelEntryIndexDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/travelentry/TravelEntryIndexDto.java index 7c81af9578b..83140729059 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/travelentry/TravelEntryIndexDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/travelentry/TravelEntryIndexDto.java @@ -3,6 +3,7 @@ import java.io.Serializable; import java.util.Date; +import de.symeda.sormas.api.common.DeletionReason; import de.symeda.sormas.api.utils.PersonalData; import de.symeda.sormas.api.utils.SensitiveData; import de.symeda.sormas.api.utils.pseudonymization.PseudonymizableIndexDto; @@ -38,6 +39,9 @@ public class TravelEntryIndexDto extends PseudonymizableIndexDto implements Seri private boolean testedNegative; private Date quarantineTo; + private DeletionReason deletionReason; + private String otherDeletionReason; + private boolean isInJurisdiction; public TravelEntryIndexDto( @@ -51,6 +55,8 @@ public TravelEntryIndexDto( boolean vaccinated, boolean testedNegative, Date quarantineTo, + DeletionReason deletionReason, + String otherDeletionReason, boolean isInJurisdiction) { super(uuid); this.externalId = externalId; @@ -62,6 +68,8 @@ public TravelEntryIndexDto( this.vaccinated = vaccinated; this.testedNegative = testedNegative; this.quarantineTo = quarantineTo; + this.deletionReason = deletionReason; + this.otherDeletionReason = otherDeletionReason; this.isInJurisdiction = isInJurisdiction; } @@ -137,6 +145,22 @@ public void setQuarantineTo(Date quarantineTo) { this.quarantineTo = quarantineTo; } + public DeletionReason getDeletionReason() { + return deletionReason; + } + + public void setDeletionReason(DeletionReason deletionReason) { + this.deletionReason = deletionReason; + } + + public String getOtherDeletionReason() { + return otherDeletionReason; + } + + public void setOtherDeletionReason(String otherDeletionReason) { + this.otherDeletionReason = otherDeletionReason; + } + public boolean isInJurisdiction() { return isInJurisdiction; } diff --git a/sormas-api/src/main/resources/captions.properties b/sormas-api/src/main/resources/captions.properties index 60e32d90c4f..8b3191830f9 100644 --- a/sormas-api/src/main/resources/captions.properties +++ b/sormas-api/src/main/resources/captions.properties @@ -366,7 +366,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +689,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1084,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1232,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1850,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1874,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2046,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2324,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2371,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/action/ActionService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/action/ActionService.java index fa724ae90ff..80f9bc86d60 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/action/ActionService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/action/ActionService.java @@ -353,7 +353,10 @@ public List getEventActionIndexList(EventCriteria criteria, cb.lower(eventResponsibleUser.get(User.LAST_NAME)), cb.selectCase() .when(cb.isNotNull(action.get(Action.LAST_MODIFIED_BY)), cb.lower(lastModifiedBy.get(User.LAST_NAME))) - .otherwise(cb.lower(creatorUser.get(User.LAST_NAME)))); + .otherwise(cb.lower(creatorUser.get(User.LAST_NAME))), + event.get(Event.CHANGE_DATE), + event.get(Event.DELETION_REASON), + event.get(Event.OTHER_DELETION_REASON)); cq.distinct(true); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/action/EventActionIndexDtoReasultTransformer.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/action/EventActionIndexDtoReasultTransformer.java index 4f6ab209351..43447497782 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/action/EventActionIndexDtoReasultTransformer.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/action/EventActionIndexDtoReasultTransformer.java @@ -8,6 +8,7 @@ import de.symeda.sormas.api.Disease; import de.symeda.sormas.api.action.ActionPriority; import de.symeda.sormas.api.action.ActionStatus; +import de.symeda.sormas.api.common.DeletionReason; import de.symeda.sormas.api.disease.DiseaseVariant; import de.symeda.sormas.api.event.EventActionIndexDto; import de.symeda.sormas.api.event.EventIdentificationSource; @@ -50,7 +51,9 @@ public Object transformTuple(Object[] objects, String[] strings) { (ActionStatus) objects[24], (ActionPriority) objects[25], actionLastModifiedBy, - actionCreatorUser); + actionCreatorUser, + (DeletionReason) objects[33], + (String) objects[34]); } @Override diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseListCriteriaBuilder.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseListCriteriaBuilder.java index 35ea62883a3..eff65fbd000 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseListCriteriaBuilder.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseListCriteriaBuilder.java @@ -232,6 +232,8 @@ public List> getCaseIndexSelections(From root, CaseQueryCo joins.getResponsibleRegion().get(Region.UUID), joins.getResponsibleDistrict().get(District.UUID), joins.getResponsibleDistrict().get(District.NAME), + root.get(Case.DELETION_REASON), + root.get(Case.OTHER_DELETION_REASON), JurisdictionHelper.booleanSelector(cb, caseService.inJurisdictionOrOwned(caseQueryContext))); } 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 740a5e11def..bf3658d3442 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 @@ -817,11 +817,14 @@ public Predicate createCriteriaFilter(CaseCrite filter = CriteriaBuilderHelper.and(cb, filter, cb.or(cb.equal(from.get(Case.ARCHIVED), false), cb.isNull(from.get(Case.ARCHIVED)))); } else if (caseCriteria.getRelevanceStatus() == EntityRelevanceStatus.ARCHIVED) { filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(Case.ARCHIVED), true)); + } else if (caseCriteria.getRelevanceStatus() == EntityRelevanceStatus.DELETED) { + filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(Case.DELETED), true)); } } - if (caseCriteria.getDeleted() != null) { - filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(Case.DELETED), caseCriteria.getDeleted())); + if (caseCriteria.getRelevanceStatus() != EntityRelevanceStatus.DELETED) { + filter = CriteriaBuilderHelper.and(cb, filter, createDefaultFilter(cb, from)); } + if (!DataHelper.isNullOrEmpty(caseCriteria.getPersonLike())) { Predicate likeFilters = CriteriaBuilderHelper.buildFreeTextSearchPredicate( cb, diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactListCriteriaBuilder.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactListCriteriaBuilder.java index fba57518da9..daa169fe995 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactListCriteriaBuilder.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactListCriteriaBuilder.java @@ -107,6 +107,8 @@ public List> getContactIndexSelections(Root contact, Conta contact.get(Contact.EXTERNAL_ID), contact.get(Contact.EXTERNAL_TOKEN), contact.get(Contact.INTERNAL_TOKEN), + contact.get(Contact.DELETION_REASON), + contact.get(Contact.OTHER_DELETION_REASON), JurisdictionHelper.booleanSelector(cb, contactService.inJurisdictionOrOwned(contactQueryContext)), JurisdictionHelper.booleanSelector( cb, diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java index d0d025927e7..ac897539531 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java @@ -1111,7 +1111,7 @@ public Predicate buildCriteriaFilter(ContactCriteria contactCriteria, ContactQue final ContactJoins joins = cqc.getJoins(); final CriteriaBuilder cb = cqc.getCriteriaBuilder(); - final From from = cqc.getRoot(); + final From from = cqc.getRoot(); Predicate filter = null; Join caze = joins.getCaze(); @@ -1285,10 +1285,12 @@ public Predicate buildCriteriaFilter(ContactCriteria contactCriteria, ContactQue .and(cb, filter, cb.and(cb.or(cb.equal(from.get(Contact.ARCHIVED), false), cb.isNull(from.get(Contact.ARCHIVED))))); } else if (contactCriteria.getRelevanceStatus() == EntityRelevanceStatus.ARCHIVED) { filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(Contact.ARCHIVED), true)); + } else if (contactCriteria.getRelevanceStatus() == EntityRelevanceStatus.DELETED) { + filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(Case.DELETED), true)); } } - if (contactCriteria.getDeleted() != null) { - filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(Case.DELETED), contactCriteria.getDeleted())); + if (contactCriteria.getRelevanceStatus() != EntityRelevanceStatus.DELETED) { + filter = CriteriaBuilderHelper.and(cb, filter, createDefaultFilter(cb, from)); } if (!DataHelper.isNullOrEmpty(contactCriteria.getPersonLike())) { 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 19551b5f147..783233a01f0 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 @@ -461,7 +461,9 @@ public List getIndexList(EventCriteria eventCriteria, Integer fir responsibleUser.get(User.LAST_NAME), JurisdictionHelper.booleanSelector(cb, service.inJurisdictionOrOwned(eventQueryContext)), event.get(Event.CHANGE_DATE), - event.get(Event.EVENT_IDENTIFICATION_SOURCE)); + event.get(Event.EVENT_IDENTIFICATION_SOURCE), + event.get(Event.DELETION_REASON), + event.get(Event.OTHER_DELETION_REASON)); Predicate filter = null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java index db28b4b996b..c3f06a24391 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java @@ -490,6 +490,8 @@ public List getIndexList( cb.max(samples.get(Sample.SAMPLE_DATE_TIME)), eventParticipant.get(EventParticipant.VACCINATION_STATUS), joins.getEventParticipantReportingUser().get(User.UUID), + eventParticipant.get(EventParticipant.DELETION_REASON), + eventParticipant.get(EventParticipant.OTHER_DELETION_REASON), inJurisdictionSelector, inJurisdictionOrOwnedSelector); cq.groupBy( @@ -509,6 +511,8 @@ public List getIndexList( eventParticipant.get(EventParticipant.VACCINATION_STATUS), joins.getEventParticipantReportingUser().get(User.ID), joins.getEventParticipantReportingUser().get(User.UUID), + eventParticipant.get(EventParticipant.DELETION_REASON), + eventParticipant.get(EventParticipant.OTHER_DELETION_REASON), inJurisdictionSelector, inJurisdictionOrOwnedSelector); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java index 7af2c39fd05..d7ecac5143c 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java @@ -234,10 +234,13 @@ public Predicate buildCriteriaFilter(EventParticipantCriteria criteria, EventPar archivedPredicate = cb.or(archivedPredicate, cb.equal(event.get(Event.ARCHIVED), true)); } filter = CriteriaBuilderHelper.and(cb, filter, archivedPredicate); + } else if (criteria.getRelevanceStatus() == EntityRelevanceStatus.DELETED) { + filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(EventParticipant.DELETED), true)); } } - - filter = CriteriaBuilderHelper.and(cb, filter, createDefaultFilter(cb, from)); + if (criteria.getRelevanceStatus() != EntityRelevanceStatus.DELETED) { + filter = CriteriaBuilderHelper.and(cb, filter, createDefaultFilter(cb, from)); + } return filter; } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java index c363239e764..ea7b52a0461 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java @@ -695,11 +695,14 @@ public Predicate buildCriteriaFilter(EventCriteria eventCriteria, EventQueryCont filter = CriteriaBuilderHelper.and(cb, filter, cb.or(cb.equal(from.get(Event.ARCHIVED), false), cb.isNull(from.get(Event.ARCHIVED)))); } else if (eventCriteria.getRelevanceStatus() == EntityRelevanceStatus.ARCHIVED) { filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(Event.ARCHIVED), true)); + } else if (eventCriteria.getRelevanceStatus() == EntityRelevanceStatus.DELETED) { + filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(Event.DELETED), true)); } } - if (eventCriteria.getDeleted() != null) { - filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(Event.DELETED), eventCriteria.getDeleted())); + if (eventCriteria.getRelevanceStatus() != EntityRelevanceStatus.DELETED) { + filter = CriteriaBuilderHelper.and(cb, filter, createDefaultFilter(cb, from)); } + if (eventCriteria.getRegion() != null) { filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(joins.getRegion().get(Region.UUID), eventCriteria.getRegion().getUuid())); } @@ -1029,7 +1032,7 @@ public Predicate inJurisdiction(EventQueryContext qc, User user) { } @Override - public Predicate inJurisdictionOrOwned(CriteriaBuilder cb, CriteriaQuery cq, From from) { + public Predicate inJurisdictionOrOwned(CriteriaBuilder cb, CriteriaQuery cq, From from) { return inJurisdictionOrOwned(new EventQueryContext(cb, cq, from)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/DirectoryImmunizationService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/DirectoryImmunizationService.java index 178a39dedce..9aac80c3add 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/DirectoryImmunizationService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/DirectoryImmunizationService.java @@ -21,6 +21,7 @@ import org.apache.commons.collections4.CollectionUtils; +import de.symeda.sormas.api.EntityRelevanceStatus; import de.symeda.sormas.api.feature.FeatureType; import de.symeda.sormas.api.feature.FeatureTypeProperty; import de.symeda.sormas.api.immunization.ImmunizationCriteria; @@ -106,6 +107,8 @@ public List getIndexList(ImmunizationCriteria criteria, In immunization.get(Immunization.END_DATE), lastVaccineType.get(LastVaccineType.VACCINE_TYPE), immunization.get(Immunization.RECOVERY_DATE), + immunization.get(Immunization.DELETION_REASON), + immunization.get(Immunization.OTHER_DELETION_REASON), JurisdictionHelper.booleanSelector(cb, isInJurisdictionOrOwned(directoryImmunizationQueryContext)), immunization.get(Immunization.CHANGE_DATE)); @@ -271,7 +274,20 @@ private Predicate buildCriteriaFilter(ImmunizationCriteria criteria, DirectoryIm filter = CriteriaBuilderHelper.applyDateFilter(cb, filter, path, criteria.getFromDate(), criteria.getToDate()); } } - filter = CriteriaBuilderHelper.and(cb, filter, cb.isFalse(from.get(Immunization.DELETED))); + + if (criteria.getRelevanceStatus() != null) { + if (criteria.getRelevanceStatus() == EntityRelevanceStatus.ACTIVE) { + filter = CriteriaBuilderHelper + .and(cb, filter, cb.or(cb.equal(from.get(Immunization.ARCHIVED), false), cb.isNull(from.get(Immunization.ARCHIVED)))); + } else if (criteria.getRelevanceStatus() == EntityRelevanceStatus.ARCHIVED) { + filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(Immunization.ARCHIVED), true)); + } else if (criteria.getRelevanceStatus() == EntityRelevanceStatus.DELETED) { + filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(Immunization.DELETED), true)); + } + } + if (criteria.getRelevanceStatus() != EntityRelevanceStatus.DELETED) { + filter = CriteriaBuilderHelper.and(cb, filter, cb.isFalse(from.get(Immunization.DELETED))); + } return filter; } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/transformers/ImmunizationIndexDtoResultTransformer.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/transformers/ImmunizationIndexDtoResultTransformer.java index 4fa3dfc72fa..a0a77bed867 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/transformers/ImmunizationIndexDtoResultTransformer.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/transformers/ImmunizationIndexDtoResultTransformer.java @@ -7,6 +7,7 @@ import de.symeda.sormas.api.Disease; import de.symeda.sormas.api.caze.AgeAndBirthDateDto; +import de.symeda.sormas.api.common.DeletionReason; import de.symeda.sormas.api.immunization.ImmunizationIndexDto; import de.symeda.sormas.api.immunization.ImmunizationManagementStatus; import de.symeda.sormas.api.immunization.ImmunizationStatus; @@ -39,7 +40,9 @@ public Object transformTuple(Object[] objects, String[] strings) { (Date) objects[16], (String) objects[17], (Date) objects[18], - (Boolean) objects[19]); + (DeletionReason) objects[19], + (String) objects[20], + (Boolean) objects[21]); } @Override diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java index bcfe53b7c74..6c2bae37f19 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java @@ -241,7 +241,9 @@ public List getIndexList(SampleCriteria sampleCriteria, Integer sample.get(Sample.ADDITIONAL_TESTING_REQUESTED), cb.isNotEmpty(sample.get(Sample.ADDITIONAL_TESTS)), districtSelect, - joins.getLab().get(Facility.UUID))); + joins.getLab().get(Facility.UUID), + sample.get(Sample.DELETION_REASON), + sample.get(Sample.OTHER_DELETION_REASON))); // Tests count subquery Subquery testCountSq = cq.subquery(Long.class); @@ -828,10 +830,12 @@ public Predicate buildCriteriaFilter(SampleCriteria criteria, SampleQueryContext filter = CriteriaBuilderHelper.and(cb, filter, assignedToActiveEntity(cb, joins)); } else if (criteria.getRelevanceStatus() == EntityRelevanceStatus.ARCHIVED) { filter = CriteriaBuilderHelper.and(cb, filter, allAssignedEntitiesAreArchived(cb, joins)); + } else if (criteria.getRelevanceStatus() == EntityRelevanceStatus.DELETED) { + filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(sample.get(Sample.DELETED), true)); } } - if (criteria.getDeleted() != null) { - filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(sample.get(Sample.DELETED), criteria.getDeleted())); + if (criteria.getRelevanceStatus() != EntityRelevanceStatus.DELETED) { + filter = CriteriaBuilderHelper.and(cb, filter, cb.isFalse(sample.get(Sample.DELETED))); } if (criteria.getCaseCodeIdLike() != null) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/TravelEntryService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/TravelEntryService.java index 171a8c6f09a..bafadd5c567 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/TravelEntryService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/TravelEntryService.java @@ -58,7 +58,6 @@ public class TravelEntryService extends BaseTravelEntryService { @EJB private DocumentService documentService; - public List getByPersonUuids(List personUuids) { List travelEntries = new LinkedList<>(); @@ -102,6 +101,8 @@ public List getIndexList(TravelEntryCriteria criteria, Inte travelEntry.get(TravelEntry.VACCINATED), travelEntry.get(TravelEntry.TESTED_NEGATIVE), travelEntry.get(TravelEntry.QUARANTINE_TO), + travelEntry.get(TravelEntry.DELETION_REASON), + travelEntry.get(TravelEntry.OTHER_DELETION_REASON), JurisdictionHelper.booleanSelector(cb, inJurisdictionOrOwned(travelEntryQueryContext)), travelEntry.get(TravelEntry.CHANGE_DATE)); @@ -284,8 +285,13 @@ private Predicate buildCriteriaFilter(TravelEntryCriteria criteria, TravelEntryQ .and(cb, filter, cb.or(cb.equal(from.get(TravelEntry.ARCHIVED), false), cb.isNull(from.get(TravelEntry.ARCHIVED)))); } else if (criteria.getRelevanceStatus() == EntityRelevanceStatus.ARCHIVED) { filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(TravelEntry.ARCHIVED), true)); + } else if (criteria.getRelevanceStatus() == EntityRelevanceStatus.DELETED) { + filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(TravelEntry.DELETED), true)); } } + if (criteria.getRelevanceStatus() != EntityRelevanceStatus.DELETED) { + filter = CriteriaBuilderHelper.and(cb, filter, createDefaultFilter(cb, from)); + } if (criteria.getReportDateFrom() != null && criteria.getReportDateTo() != null) { filter = CriteriaBuilderHelper @@ -296,10 +302,6 @@ private Predicate buildCriteriaFilter(TravelEntryCriteria criteria, TravelEntryQ filter = CriteriaBuilderHelper.and(cb, filter, cb.lessThanOrEqualTo(from.get(TravelEntry.REPORT_DATE), criteria.getReportDateTo())); } - if (criteria.getDeleted() != null) { - filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(TravelEntry.DELETED), criteria.getDeleted())); - } - if (!DataHelper.isNullOrEmpty(criteria.getNameUuidExternalIDLike())) { Predicate likeFilters = CriteriaBuilderHelper.buildFreeTextSearchPredicate( cb, @@ -314,7 +316,6 @@ private Predicate buildCriteriaFilter(TravelEntryCriteria criteria, TravelEntryQ filter = CriteriaBuilderHelper.and(cb, filter, likeFilters); } - filter = CriteriaBuilderHelper.and(cb, filter, createDefaultFilter(cb, from)); return filter; } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/transformers/TravelEntryIndexDtoResultTransformer.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/transformers/TravelEntryIndexDtoResultTransformer.java index 0a886963984..5e7d4b6aea3 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/transformers/TravelEntryIndexDtoResultTransformer.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/transformers/TravelEntryIndexDtoResultTransformer.java @@ -6,6 +6,7 @@ import org.apache.commons.lang3.StringUtils; import org.hibernate.transform.ResultTransformer; +import de.symeda.sormas.api.common.DeletionReason; import de.symeda.sormas.api.travelentry.TravelEntryIndexDto; public class TravelEntryIndexDtoResultTransformer implements ResultTransformer { @@ -25,7 +26,9 @@ public Object transformTuple(Object[] objects, String[] strings) { (boolean) objects[8], (boolean) objects[9], (Date) objects[10], - (boolean) objects[11]); + (DeletionReason) objects[11], + (String) objects[12], + (boolean) objects[13]); } @Override diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjbTest.java index c0675bfaa7d..c8d970e12cd 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjbTest.java @@ -443,7 +443,7 @@ public void testEventParticipantWithArchivedEvent() { EventParticipantCriteria eventParticipantCriteria = new EventParticipantCriteria(); eventParticipantCriteria.setEvent(event.toReference()); - eventParticipantCriteria.relevanceStatus(EntityRelevanceStatus.ALL); + eventParticipantCriteria.relevanceStatus(EntityRelevanceStatus.ACTIVE_AND_ARCHIVED); List eventParticipantIndexDtos = getEventParticipantFacade().getIndexList(eventParticipantCriteria, 0, 100, null); assertEquals(2, eventParticipantIndexDtos.size()); @@ -464,7 +464,7 @@ public void testEventParticipantWithArchivedEvent() { editArchivedFeatureConfiguration.setEnabled(false); getFeatureConfigurationFacade().saveFeatureConfiguration(editArchivedFeatureConfiguration, FeatureType.EDIT_ARCHIVED_ENTITIES); - eventParticipantCriteria.relevanceStatus(EntityRelevanceStatus.ALL); + eventParticipantCriteria.relevanceStatus(EntityRelevanceStatus.ACTIVE_AND_ARCHIVED); eventParticipantIndexDtos = getEventParticipantFacade().getIndexList(eventParticipantCriteria, 0, 100, null); assertEquals(2, eventParticipantIndexDtos.size()); eventParticipantUuids = eventParticipantIndexDtos.stream().map(ev -> ev.getUuid()).collect(Collectors.toList()); diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/task/TaskFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/task/TaskFacadeEjbTest.java index 6e511d54ce5..d98b50930ff 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/task/TaskFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/task/TaskFacadeEjbTest.java @@ -104,7 +104,8 @@ public void testTaskDirectoryForDeletedLinkedCase() { getCaseFacade().delete(caze.getUuid(), new DeletionDetails()); - List tasks = getTaskFacade().getIndexList(new TaskCriteria().relevanceStatus(EntityRelevanceStatus.ALL), 0, 100, null); + List tasks = + getTaskFacade().getIndexList(new TaskCriteria().relevanceStatus(EntityRelevanceStatus.ACTIVE_AND_ARCHIVED), 0, 100, null); assertEquals(0, tasks.size()); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigns/CampaignsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigns/CampaignsView.java index c461e287329..a8d26b66b29 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigns/CampaignsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigns/CampaignsView.java @@ -123,7 +123,8 @@ private HorizontalLayout createFilterBar() { relevanceStatusFilter.addItems((Object[]) EntityRelevanceStatus.values()); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE, I18nProperties.getCaption(Captions.campaignActiveCampaigns)); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ARCHIVED, I18nProperties.getCaption(Captions.campaignArchivedCampaigns)); - relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ALL, I18nProperties.getCaption(Captions.campaignAllCampaigns)); + relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE_AND_ARCHIVED, I18nProperties.getCaption(Captions.campaignAllCampaigns)); + relevanceStatusFilter.removeItem(EntityRelevanceStatus.DELETED); relevanceStatusFilter.addValueChangeListener(e -> { criteria.relevanceStatus((EntityRelevanceStatus) e.getProperty().getValue()); navigateTo(criteria); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/AbstractCaseGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/AbstractCaseGrid.java index b79d921dc47..c33e7f8d195 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/AbstractCaseGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/AbstractCaseGrid.java @@ -127,6 +127,17 @@ protected void initColumns() { visitsColumn.setId(NUMBER_OF_VISITS); visitsColumn.setSortable(false); + Column deleteColumn = addColumn(entry -> { + if (entry.getDeletionReason() != null) { + return entry.getDeletionReason() + (entry.getOtherDeletionReason() != null ? ": " + entry.getOtherDeletionReason() : ""); + } else { + return "-"; + } + }); + deleteColumn.setId(DELETE_REASON_COLUMN); + deleteColumn.setSortable(false); + deleteColumn.setCaption(I18nProperties.getCaption(Captions.deletionReason)); + addComponentColumn(indexDto -> { Label label = new Label(indexDto.getCompleteness() != null ? new DecimalFormat("#").format(indexDto.getCompleteness() * 100) + " %" : "-"); @@ -187,6 +198,10 @@ protected void initColumns() { removeColumn(CaseIndexDto.CREATION_DATE); } + if (!UserProvider.getCurrent().hasUserRight(UserRight.CASE_DELETE)) { + removeColumn(DELETE_REASON_COLUMN); + } + for (Column column : getColumns()) { column.setCaption( I18nProperties.findPrefixCaptionWithDefault( @@ -230,7 +245,8 @@ protected Stream getGridColumns() { Stream.of(CaseIndexDto.QUARANTINE_TO, CaseIndexDto.CREATION_DATE), getFollowUpColumns(), Stream.of(CaseIndexDto.VACCINATION_STATUS), - Stream.of(COLUMN_COMPLETENESS)) + Stream.of(COLUMN_COMPLETENESS), + Stream.of(DELETE_REASON_COLUMN)) .flatMap(Function.identity()); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasesView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasesView.java index efc0f99f932..809a3b973b1 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasesView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasesView.java @@ -674,12 +674,19 @@ public HorizontalLayout createStatusFilterBar() { } relevanceStatusFilter = ComboBoxHelper.createComboBoxV7(); relevanceStatusFilter.setId("relevanceStatus"); - relevanceStatusFilter.setWidth(140, Unit.PIXELS); + relevanceStatusFilter.setWidth(210, Unit.PIXELS); relevanceStatusFilter.setNullSelectionAllowed(false); relevanceStatusFilter.addItems((Object[]) EntityRelevanceStatus.values()); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE, I18nProperties.getCaption(Captions.caseActiveCases)); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ARCHIVED, I18nProperties.getCaption(Captions.caseArchivedCases)); - relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ALL, I18nProperties.getCaption(Captions.caseAllCases)); + relevanceStatusFilter + .setItemCaption(EntityRelevanceStatus.ACTIVE_AND_ARCHIVED, I18nProperties.getCaption(Captions.caseAllActiveAndArchivedCases)); + + if (UserProvider.getCurrent().hasUserRight(UserRight.CASE_DELETE)) { + relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.DELETED, I18nProperties.getCaption(Captions.caseDeletedCases)); + } else { + relevanceStatusFilter.removeItem(EntityRelevanceStatus.DELETED); + } relevanceStatusFilter.addValueChangeListener(e -> { if (relevanceStatusInfoLabel != null) { relevanceStatusInfoLabel.setVisible(EntityRelevanceStatus.ARCHIVED.equals(e.getProperty().getValue())); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/AreasView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/AreasView.java index 782f17b5f12..7426c826818 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/AreasView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/AreasView.java @@ -166,7 +166,7 @@ private HorizontalLayout createFilterBar() { filterRelevanceStatus.setId("relevanceStatus"); filterRelevanceStatus.setWidth(220, Unit.PERCENTAGE); filterRelevanceStatus.setEmptySelectionAllowed(false); - filterRelevanceStatus.setItems(EntityRelevanceStatus.values()); + filterRelevanceStatus.setItems((EntityRelevanceStatus[]) EntityRelevanceStatus.getAllExceptDeleted()); filterRelevanceStatus.setItemCaptionGenerator(status -> { switch (status) { case ACTIVE: @@ -187,25 +187,33 @@ private HorizontalLayout createFilterBar() { if (UserProvider.getCurrent().hasUserRight(UserRight.PERFORM_BULK_OPERATIONS)) { dropdownBulkOperations = MenuBarHelper.createDropDown( Captions.bulkActions, - new MenuBarHelper.MenuBarItem(I18nProperties.getCaption(Captions.actionArchiveInfrastructure), VaadinIcons.ARCHIVE, selectedItem -> { - ControllerProvider.getInfrastructureController() - .archiveOrDearchiveAllSelectedItems( - true, - grid.asMultiSelect().getSelectedItems(), - InfrastructureType.AREA, - () -> navigateTo(criteria)); - }, EntityRelevanceStatus.ACTIVE.equals(criteria.getRelevanceStatus())), - new MenuBarHelper.MenuBarItem(I18nProperties.getCaption(Captions.actionDearchiveInfrastructure), VaadinIcons.ARCHIVE, selectedItem -> { - ControllerProvider.getInfrastructureController() - .archiveOrDearchiveAllSelectedItems( - false, - grid.asMultiSelect().getSelectedItems(), - InfrastructureType.AREA, - () -> navigateTo(criteria)); - }, EntityRelevanceStatus.ARCHIVED.equals(criteria.getRelevanceStatus()))); - - dropdownBulkOperations - .setVisible(viewConfiguration.isInEagerMode() && !EntityRelevanceStatus.ALL.equals(criteria.getRelevanceStatus())); + new MenuBarHelper.MenuBarItem( + I18nProperties.getCaption(Captions.actionArchiveInfrastructure), + VaadinIcons.ARCHIVE, + selectedItem -> { + ControllerProvider.getInfrastructureController() + .archiveOrDearchiveAllSelectedItems( + true, + grid.asMultiSelect().getSelectedItems(), + InfrastructureType.AREA, + () -> navigateTo(criteria)); + }, + EntityRelevanceStatus.ACTIVE.equals(criteria.getRelevanceStatus())), + new MenuBarHelper.MenuBarItem( + I18nProperties.getCaption(Captions.actionDearchiveInfrastructure), + VaadinIcons.ARCHIVE, + selectedItem -> { + ControllerProvider.getInfrastructureController() + .archiveOrDearchiveAllSelectedItems( + false, + grid.asMultiSelect().getSelectedItems(), + InfrastructureType.AREA, + () -> navigateTo(criteria)); + }, + EntityRelevanceStatus.ARCHIVED.equals(criteria.getRelevanceStatus()))); + + dropdownBulkOperations.setVisible( + viewConfiguration.isInEagerMode() && !EntityRelevanceStatus.ACTIVE_AND_ARCHIVED.equals(criteria.getRelevanceStatus())); actionButtonsLayout.addComponent(dropdownBulkOperations); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/CommunitiesView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/CommunitiesView.java index 57b4bfe9a2b..07cbb5f1773 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/CommunitiesView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/CommunitiesView.java @@ -251,11 +251,12 @@ private HorizontalLayout createFilterBar() { relevanceStatusFilter.setId("relevanceStatus"); relevanceStatusFilter.setWidth(220, Unit.PERCENTAGE); relevanceStatusFilter.setNullSelectionAllowed(false); - relevanceStatusFilter.addItems((Object[]) EntityRelevanceStatus.values()); + relevanceStatusFilter.addItems(EntityRelevanceStatus.getAllExceptDeleted()); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE, I18nProperties.getCaption(Captions.communityActiveCommunities)); relevanceStatusFilter .setItemCaption(EntityRelevanceStatus.ARCHIVED, I18nProperties.getCaption(Captions.communityArchivedCommunities)); - relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ALL, I18nProperties.getCaption(Captions.communityAllCommunities)); + relevanceStatusFilter + .setItemCaption(EntityRelevanceStatus.ACTIVE_AND_ARCHIVED, I18nProperties.getCaption(Captions.communityAllCommunities)); relevanceStatusFilter.addValueChangeListener(e -> { criteria.relevanceStatus((EntityRelevanceStatus) e.getProperty().getValue()); navigateTo(criteria); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/ContinentsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/ContinentsView.java index a95d3b65a03..0863f850ef0 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/ContinentsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/ContinentsView.java @@ -212,10 +212,11 @@ private HorizontalLayout createFilterBar() { relevanceStatusFilter.setId("relevanceStatus"); relevanceStatusFilter.setWidth(220, Unit.PERCENTAGE); relevanceStatusFilter.setNullSelectionAllowed(false); - relevanceStatusFilter.addItems((Object[]) EntityRelevanceStatus.values()); + relevanceStatusFilter.addItems(EntityRelevanceStatus.getAllExceptDeleted()); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE, I18nProperties.getCaption(Captions.continentActiveContinents)); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ARCHIVED, I18nProperties.getCaption(Captions.continentArchivedContinents)); - relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ALL, I18nProperties.getCaption(Captions.continentAllContinents)); + relevanceStatusFilter + .setItemCaption(EntityRelevanceStatus.ACTIVE_AND_ARCHIVED, I18nProperties.getCaption(Captions.continentAllContinents)); relevanceStatusFilter.addValueChangeListener(e -> { criteria.relevanceStatus((EntityRelevanceStatus) e.getProperty().getValue()); navigateTo(criteria); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/CountriesView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/CountriesView.java index 25951178790..078436a2da2 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/CountriesView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/CountriesView.java @@ -232,10 +232,11 @@ private HorizontalLayout createFilterBar() { relevanceStatusFilter.setId("relevanceStatus"); relevanceStatusFilter.setWidth(220, Unit.PERCENTAGE); relevanceStatusFilter.setNullSelectionAllowed(false); - relevanceStatusFilter.addItems((Object[]) EntityRelevanceStatus.values()); + relevanceStatusFilter.addItems(EntityRelevanceStatus.getAllExceptDeleted()); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE, I18nProperties.getCaption(Captions.countryActiveCountries)); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ARCHIVED, I18nProperties.getCaption(Captions.countryArchivedCountries)); - relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ALL, I18nProperties.getCaption(Captions.countryAllCountries)); + relevanceStatusFilter + .setItemCaption(EntityRelevanceStatus.ACTIVE_AND_ARCHIVED, I18nProperties.getCaption(Captions.countryAllCountries)); relevanceStatusFilter.addValueChangeListener(e -> { criteria.relevanceStatus((EntityRelevanceStatus) e.getProperty().getValue()); navigateTo(criteria); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/DistrictsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/DistrictsView.java index 511a3a3fe2e..49672291995 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/DistrictsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/DistrictsView.java @@ -238,10 +238,11 @@ private HorizontalLayout createFilterBar() { relevanceStatusFilter.setId("relevanceStatus"); relevanceStatusFilter.setWidth(220, Unit.PERCENTAGE); relevanceStatusFilter.setNullSelectionAllowed(false); - relevanceStatusFilter.addItems((Object[]) EntityRelevanceStatus.values()); + relevanceStatusFilter.addItems(EntityRelevanceStatus.getAllExceptDeleted()); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE, I18nProperties.getCaption(Captions.districtActiveDistricts)); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ARCHIVED, I18nProperties.getCaption(Captions.districtArchivedDistricts)); - relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ALL, I18nProperties.getCaption(Captions.districtAllDistricts)); + relevanceStatusFilter + .setItemCaption(EntityRelevanceStatus.ACTIVE_AND_ARCHIVED, I18nProperties.getCaption(Captions.districtAllDistricts)); relevanceStatusFilter.addValueChangeListener(e -> { criteria.relevanceStatus((EntityRelevanceStatus) e.getProperty().getValue()); navigateTo(criteria); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/FacilitiesView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/FacilitiesView.java index 16dba3ac32b..81ff12cdff7 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/FacilitiesView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/FacilitiesView.java @@ -348,11 +348,12 @@ private HorizontalLayout createFilterBar() { relevanceStatusFilter.setWidth(220, Unit.PERCENTAGE); relevanceStatusFilter.setNullSelectionAllowed(false); - relevanceStatusFilter.addItems((Object[]) EntityRelevanceStatus.values()); + relevanceStatusFilter.addItems(EntityRelevanceStatus.getAllExceptDeleted()); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE, I18nProperties.getCaption(Captions.facilityActiveFacilities)); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ARCHIVED, I18nProperties.getCaption(Captions.facilityArchivedFacilities)); - relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ALL, I18nProperties.getCaption(Captions.facilityAllFacilities)); + relevanceStatusFilter + .setItemCaption(EntityRelevanceStatus.ACTIVE_AND_ARCHIVED, I18nProperties.getCaption(Captions.facilityAllFacilities)); relevanceStatusFilter.addValueChangeListener(e -> { criteria.relevanceStatus((EntityRelevanceStatus) e.getProperty().getValue()); navigateTo(criteria); @@ -398,8 +399,8 @@ public void run() { }, EntityRelevanceStatus.ARCHIVED.equals(criteria.getRelevanceStatus()))); - bulkOperationsDropdown - .setVisible(viewConfiguration.isInEagerMode() && !EntityRelevanceStatus.ALL.equals(criteria.getRelevanceStatus())); + bulkOperationsDropdown.setVisible( + viewConfiguration.isInEagerMode() && !EntityRelevanceStatus.ACTIVE_AND_ARCHIVED.equals(criteria.getRelevanceStatus())); actionButtonsLayout.addComponent(bulkOperationsDropdown); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/PointsOfEntryView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/PointsOfEntryView.java index 895534bd90b..fd96815d9ca 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/PointsOfEntryView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/PointsOfEntryView.java @@ -123,8 +123,11 @@ public PointsOfEntryView() { exportButton.setDescription(I18nProperties.getDescription(Descriptions.descExportButton)); addHeaderComponent(exportButton); - StreamResource streamResource = GridExportStreamResource - .createStreamResourceWithSelectedItems(grid, this::getSelectedRows, ExportEntityName.POINTS_OF_ENTRY, PointsOfEntryGrid.ACTION_BTN_ID); + StreamResource streamResource = GridExportStreamResource.createStreamResourceWithSelectedItems( + grid, + this::getSelectedRows, + ExportEntityName.POINTS_OF_ENTRY, + PointsOfEntryGrid.ACTION_BTN_ID); FileDownloader fileDownloader = new FileDownloader(streamResource); fileDownloader.extend(exportButton); } @@ -271,12 +274,13 @@ private HorizontalLayout createFilterBar() { relevanceStatusFilter.setId("relevanceStatus"); relevanceStatusFilter.setWidth(220, Unit.PERCENTAGE); relevanceStatusFilter.setNullSelectionAllowed(false); - relevanceStatusFilter.addItems((Object[]) EntityRelevanceStatus.values()); + relevanceStatusFilter.addItems(EntityRelevanceStatus.getAllExceptDeleted()); relevanceStatusFilter .setItemCaption(EntityRelevanceStatus.ACTIVE, I18nProperties.getCaption(Captions.pointOfEntryActivePointsOfEntry)); relevanceStatusFilter .setItemCaption(EntityRelevanceStatus.ARCHIVED, I18nProperties.getCaption(Captions.pointOfEntryArchivedPointsOfEntry)); - relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ALL, I18nProperties.getCaption(Captions.pointOfEntryAllPointsOfEntry)); + relevanceStatusFilter + .setItemCaption(EntityRelevanceStatus.ACTIVE_AND_ARCHIVED, I18nProperties.getCaption(Captions.pointOfEntryAllPointsOfEntry)); relevanceStatusFilter.addValueChangeListener(e -> { criteria.relevanceStatus((EntityRelevanceStatus) e.getProperty().getValue()); navigateTo(criteria); @@ -312,8 +316,8 @@ private HorizontalLayout createFilterBar() { }, EntityRelevanceStatus.ARCHIVED.equals(criteria.getRelevanceStatus()))); - bulkOperationsDropdown - .setVisible(viewConfiguration.isInEagerMode() && !EntityRelevanceStatus.ALL.equals(criteria.getRelevanceStatus())); + bulkOperationsDropdown.setVisible( + viewConfiguration.isInEagerMode() && !EntityRelevanceStatus.ACTIVE_AND_ARCHIVED.equals(criteria.getRelevanceStatus())); actionButtonsLayout.addComponent(bulkOperationsDropdown); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/RegionsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/RegionsView.java index 1a7ee86d4bc..97686918e1e 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/RegionsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/RegionsView.java @@ -215,10 +215,10 @@ private HorizontalLayout createFilterBar() { relevanceStatusFilter.setId("relevanceStatus"); relevanceStatusFilter.setWidth(220, Unit.PERCENTAGE); relevanceStatusFilter.setNullSelectionAllowed(false); - relevanceStatusFilter.addItems((Object[]) EntityRelevanceStatus.values()); + relevanceStatusFilter.addItems(EntityRelevanceStatus.getAllExceptDeleted()); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE, I18nProperties.getCaption(Captions.regionActiveRegions)); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ARCHIVED, I18nProperties.getCaption(Captions.regionArchivedRegions)); - relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ALL, I18nProperties.getCaption(Captions.regionAllRegions)); + relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE_AND_ARCHIVED, I18nProperties.getCaption(Captions.regionAllRegions)); relevanceStatusFilter.addValueChangeListener(e -> { criteria.relevanceStatus((EntityRelevanceStatus) e.getProperty().getValue()); navigateTo(criteria); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/SubcontinentsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/SubcontinentsView.java index f46769a9ac3..0f5b7321d35 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/SubcontinentsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/SubcontinentsView.java @@ -226,12 +226,13 @@ private HorizontalLayout createFilterBar() { relevanceStatusFilter.setId("relevanceStatus"); relevanceStatusFilter.setWidth(220, Unit.PERCENTAGE); relevanceStatusFilter.setNullSelectionAllowed(false); - relevanceStatusFilter.addItems((Object[]) EntityRelevanceStatus.values()); + relevanceStatusFilter.addItems(EntityRelevanceStatus.getAllExceptDeleted()); relevanceStatusFilter .setItemCaption(EntityRelevanceStatus.ACTIVE, I18nProperties.getCaption(Captions.subcontinentActiveSubcontinents)); relevanceStatusFilter .setItemCaption(EntityRelevanceStatus.ARCHIVED, I18nProperties.getCaption(Captions.subcontinentArchivedSubcontinents)); - relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ALL, I18nProperties.getCaption(Captions.subcontinentAllSubcontinents)); + relevanceStatusFilter + .setItemCaption(EntityRelevanceStatus.ACTIVE_AND_ARCHIVED, I18nProperties.getCaption(Captions.subcontinentAllSubcontinents)); relevanceStatusFilter.addValueChangeListener(e -> { criteria.relevanceStatus((EntityRelevanceStatus) e.getProperty().getValue()); navigateTo(criteria); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/AbstractContactGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/AbstractContactGrid.java index f527c117372..daa2c442d5c 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/AbstractContactGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/AbstractContactGrid.java @@ -131,6 +131,17 @@ protected void initColumns() { visitsColumn.setId(NUMBER_OF_VISITS); visitsColumn.setSortable(false); + Column deleteColumn = addColumn(entry -> { + if (entry.getDeletionReason() != null) { + return entry.getDeletionReason() + (entry.getOtherDeletionReason() != null ? ": " + entry.getOtherDeletionReason() : ""); + } else { + return "-"; + } + }); + deleteColumn.setId(DELETE_REASON_COLUMN); + deleteColumn.setSortable(false); + deleteColumn.setCaption(I18nProperties.getCaption(Captions.deletionReason)); + addComponentColumn(indexDto -> { Label label = new Label(indexDto.getCompleteness() != null ? new DecimalFormat("#").format(indexDto.getCompleteness() * 100) + " %" : "-"); @@ -179,6 +190,10 @@ protected void initColumns() { getColumn(ContactIndexDto.SYMPTOM_JOURNAL_STATUS).setHidden(true); } + if (!UserProvider.getCurrent().hasUserRight(UserRight.CONTACT_DELETE)) { + removeColumn(DELETE_REASON_COLUMN); + } + for (Column column : getColumns()) { column.setCaption( I18nProperties.findPrefixCaptionWithDefault( @@ -218,7 +233,8 @@ protected Stream getColumnList() { .filter( column -> FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.TASK_MANAGEMENT) && UserProvider.getCurrent().hasUserRight(UserRight.TASK_VIEW)), - Stream.of(COLUMN_COMPLETENESS)) + Stream.of(COLUMN_COMPLETENESS), + Stream.of(DELETE_REASON_COLUMN)) .flatMap(s -> s); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsView.java index 683984b1caa..7466d45ca6a 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsView.java @@ -483,12 +483,21 @@ public HorizontalLayout createStatusFilterBar() { relevanceStatusFilter = ComboBoxHelper.createComboBoxV7(); relevanceStatusFilter.setId("relevanceStatus"); - relevanceStatusFilter.setWidth(140, Unit.PERCENTAGE); + relevanceStatusFilter.setWidth(220, Unit.PIXELS); relevanceStatusFilter.setNullSelectionAllowed(false); relevanceStatusFilter.addItems((Object[]) EntityRelevanceStatus.values()); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE, I18nProperties.getCaption(Captions.contactActiveContacts)); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ARCHIVED, I18nProperties.getCaption(Captions.contactArchivedContacts)); - relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ALL, I18nProperties.getCaption(Captions.contactAllContacts)); + relevanceStatusFilter.setItemCaption( + EntityRelevanceStatus.ACTIVE_AND_ARCHIVED, + I18nProperties.getCaption(Captions.contactAllActiveAndArchiveContacts)); + + if (UserProvider.getCurrent().hasUserRight(UserRight.CONTACT_DELETE)) { + relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.DELETED, I18nProperties.getCaption(Captions.contactDeletedContacts)); + } else { + relevanceStatusFilter.removeItem(EntityRelevanceStatus.DELETED); + } + relevanceStatusFilter.addValueChangeListener(e -> { if (relevanceStatusInfoLabel != null) { relevanceStatusInfoLabel.setVisible(EntityRelevanceStatus.ARCHIVED.equals(e.getProperty().getValue())); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventActionsGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventActionsGrid.java index e9f25c030b0..1bbae096308 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventActionsGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventActionsGrid.java @@ -33,9 +33,11 @@ import de.symeda.sormas.api.event.EventHelper; import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.i18n.I18nProperties; +import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.api.utils.SortProperty; import de.symeda.sormas.ui.ControllerProvider; +import de.symeda.sormas.ui.UserProvider; import de.symeda.sormas.ui.ViewModelProviders; import de.symeda.sormas.ui.utils.DateFormatHelper; import de.symeda.sormas.ui.utils.FilteredGrid; @@ -65,6 +67,8 @@ public EventActionsGrid(EventCriteria eventCriteria, Class v Language userLanguage = I18nProperties.getUserLanguage(); + createDeletionReasonColumn(); + setColumns( EventActionIndexDto.EVENT_UUID, EventActionIndexDto.EVENT_TITLE, @@ -85,7 +89,8 @@ public EventActionsGrid(EventCriteria eventCriteria, Class v EventActionIndexDto.ACTION_DATE, EventActionIndexDto.ACTION_STATUS, EventActionIndexDto.ACTION_PRIORITY, - createLastModifiedByOrCreatorColumn(this)); + createLastModifiedByOrCreatorColumn(this), + DELETE_REASON_COLUMN); ((Column) getColumn(EventActionIndexDto.EVENT_UUID)).setRenderer(new UuidRenderer()); ((Column) getColumn(EventActionIndexDto.ACTION_CREATION_DATE)) @@ -148,6 +153,21 @@ private String createEventEvolutionDateColumn(FilteredGrid deleteColumn = addColumn(entry -> { + if (entry.getDeletionReason() != null) { + return entry.getDeletionReason() + (entry.getOtherDeletionReason() != null ? ": " + entry.getOtherDeletionReason() : ""); + } else { + return "-"; + } + }); + deleteColumn.setId(DELETE_REASON_COLUMN); + deleteColumn.setSortable(false); + deleteColumn.setCaption(I18nProperties.getCaption(Captions.deletionReason)); + } + } + public void reload() { if (getSelectionModel().isUserSelectionAllowed()) { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventGrid.java index b4c33030e18..47dbe1ff4d1 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventGrid.java @@ -175,6 +175,20 @@ public EventGrid(EventCriteria criteria, Class viewClass) { EventIndexDto.CONTACT_COUNT, EventIndexDto.CONTACT_COUNT_SOURCE_IN_EVENT)); + if (UserProvider.getCurrent().hasUserRight(UserRight.EVENT_DELETE)) { + Column deleteColumn = addColumn(entry -> { + if (entry.getDeletionReason() != null) { + return entry.getDeletionReason() + (entry.getOtherDeletionReason() != null ? ": " + entry.getOtherDeletionReason() : ""); + } else { + return "-"; + } + }); + deleteColumn.setId(DELETE_REASON_COLUMN); + deleteColumn.setSortable(false); + deleteColumn.setCaption(I18nProperties.getCaption(Captions.deletionReason)); + columnIds.add(DELETE_REASON_COLUMN); + } + setColumns(columnIds.toArray(new String[columnIds.size()])); getColumn(EventIndexDto.PARTICIPANT_COUNT).setSortable(false); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventParticipantsGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventParticipantsGrid.java index 9d9b10e437e..d5ca75b004f 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventParticipantsGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventParticipantsGrid.java @@ -90,6 +90,17 @@ public EventParticipantsGrid(EventParticipantCriteria criteria) { return NO_CASE_CREATE != uuid; })); + Column deleteColumn = addColumn(entry -> { + if (entry.getDeletionReason() != null) { + return entry.getDeletionReason() + (entry.getOtherDeletionReason() != null ? ": " + entry.getOtherDeletionReason() : ""); + } else { + return "-"; + } + }); + deleteColumn.setId(DELETE_REASON_COLUMN); + deleteColumn.setSortable(false); + deleteColumn.setCaption(I18nProperties.getCaption(Captions.deletionReason)); + Language userLanguage = I18nProperties.getUserLanguage(); setColumns( EventParticipantIndexDto.UUID, @@ -103,7 +114,8 @@ public EventParticipantsGrid(EventParticipantCriteria criteria) { EventParticipantIndexDto.CONTACT_COUNT, SampleIndexDto.PATHOGEN_TEST_RESULT, SampleIndexDto.SAMPLE_DATE_TIME, - EventParticipantIndexDto.VACCINATION_STATUS); + EventParticipantIndexDto.VACCINATION_STATUS, + DELETE_REASON_COLUMN); ((Column) getColumn(SampleIndexDto.SAMPLE_DATE_TIME)) .setRenderer(new DateRenderer(DateHelper.getLocalDateTimeFormat(userLanguage))); ((Column) getColumn(EventParticipantIndexDto.UUID)).setRenderer(new UuidRenderer()); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventParticipantsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventParticipantsView.java index 486d7a9593a..8a05c825def 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventParticipantsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventParticipantsView.java @@ -298,7 +298,7 @@ public HorizontalLayout createTopBar() { private boolean shouldDisableButton() { return FacadeProvider.getFeatureConfigurationFacade().isFeatureDisabled(FeatureType.EDIT_ARCHIVED_ENTITIES) - && FacadeProvider.getEventFacade().isArchived(getEventRef().getUuid()); + && FacadeProvider.getEventFacade().isArchived(getEventRef().getUuid()); } private Set getSelectedRows() { @@ -379,7 +379,7 @@ public HorizontalLayout createStatusFilterBar() { eventParticipantRelevanceStatusFilter = buildRelevanceStatusFilter( Captions.eventParticipantActiveEventParticipants, Captions.eventParticipantArchivedEventParticipants, - Captions.eventParticipantAllEventParticipants); + Captions.eventParticipantActiveAndArchivedEventParticipants); eventParticipantRelevanceStatusFilter.addValueChangeListener(e -> { if (relevanceStatusInfoLabel != null) { @@ -418,7 +418,15 @@ private ComboBox buildRelevanceStatusFilter( relevanceStatusFilter.addItems((Object[]) EntityRelevanceStatus.values()); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE, I18nProperties.getCaption(eventParticipantActiveCaption)); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ARCHIVED, I18nProperties.getCaption(eventParticipantArchivedCaption)); - relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ALL, I18nProperties.getCaption(eventParticipantAllCaption)); + relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE_AND_ARCHIVED, I18nProperties.getCaption(eventParticipantAllCaption)); + + if (UserProvider.getCurrent().hasUserRight(UserRight.EVENTPARTICIPANT_DELETE)) { + relevanceStatusFilter + .setItemCaption(EntityRelevanceStatus.DELETED, I18nProperties.getCaption(Captions.eventParticipantDeletedEventParticipants)); + } else { + relevanceStatusFilter.removeItem(EntityRelevanceStatus.DELETED); + } + return relevanceStatusFilter; } @@ -433,7 +441,7 @@ public void updateFilterComponents() { if (criteria.getRelevanceStatus() == null) { criteria.relevanceStatus(EntityRelevanceStatus.ACTIVE); boolean archived = FacadeProvider.getEventFacade().isArchived(getEventRef().getUuid()); - eventParticipantRelevanceStatusFilter.setValue(archived ? EntityRelevanceStatus.ALL : criteria.getRelevanceStatus()); + eventParticipantRelevanceStatusFilter.setValue(archived ? EntityRelevanceStatus.ACTIVE_AND_ARCHIVED : criteria.getRelevanceStatus()); } else { eventParticipantRelevanceStatusFilter.setValue(criteria.getRelevanceStatus()); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventsView.java index e738e4fcea0..d9f5712800f 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventsView.java @@ -493,6 +493,7 @@ public HorizontalLayout createStatusFilterBar() { if (isGroupViewType()) { groupRelevanceStatusFilter = buildRelevanceStatus(Captions.eventActiveGroups, Captions.eventArchivedGroups, Captions.eventAllGroups); + groupRelevanceStatusFilter.removeItem(EntityRelevanceStatus.DELETED); groupRelevanceStatusFilter.addValueChangeListener(e -> { eventGroupCriteria.relevanceStatus((EntityRelevanceStatus) e.getProperty().getValue()); navigateTo(eventGroupCriteria); @@ -516,7 +517,7 @@ public HorizontalLayout createStatusFilterBar() { } eventRelevanceStatusFilter = - buildRelevanceStatus(Captions.eventActiveEvents, Captions.eventArchivedEvents, Captions.eventAllEvents); + buildRelevanceStatus(Captions.eventActiveEvents, Captions.eventArchivedEvents, Captions.eventAllActiveAndArchivedEvents); eventRelevanceStatusFilter.addValueChangeListener(e -> { if (relevanceStatusInfoLabel != null) { relevanceStatusInfoLabel.setVisible(EntityRelevanceStatus.ARCHIVED.equals(e.getProperty().getValue())); @@ -740,13 +741,20 @@ private ExportConfigurationDto buildDetailedExportConfiguration() { private ComboBox buildRelevanceStatus(String eventActiveCaption, String eventArchivedCaption, String eventAllCaption) { ComboBox relevanceStatusFilter = ComboBoxHelper.createComboBoxV7(); relevanceStatusFilter.setId("relevanceStatusFilter"); - relevanceStatusFilter.setWidth(140, Unit.PERCENTAGE); + relevanceStatusFilter.setWidth(210, Unit.PIXELS); relevanceStatusFilter.setNullSelectionAllowed(false); relevanceStatusFilter.setTextInputAllowed(false); relevanceStatusFilter.addItems((Object[]) EntityRelevanceStatus.values()); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE, I18nProperties.getCaption(eventActiveCaption)); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ARCHIVED, I18nProperties.getCaption(eventArchivedCaption)); - relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ALL, I18nProperties.getCaption(eventAllCaption)); + relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE_AND_ARCHIVED, I18nProperties.getCaption(eventAllCaption)); + + if (UserProvider.getCurrent().hasUserRight(UserRight.EVENT_DELETE)) { + relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.DELETED, I18nProperties.getCaption(Captions.eventDeletedEvents)); + } else { + relevanceStatusFilter.removeItem(EntityRelevanceStatus.DELETED); + } + relevanceStatusFilter.setCaption(""); return relevanceStatusFilter; } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/ImmunizationsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/ImmunizationsView.java index 0d77fe0dadf..1bbda4f8c3e 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/ImmunizationsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/ImmunizationsView.java @@ -1,9 +1,24 @@ package de.symeda.sormas.ui.immunization; +import java.util.Objects; + +import com.vaadin.icons.VaadinIcons; import com.vaadin.navigator.ViewChangeListener; +import com.vaadin.shared.ui.ContentMode; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; import com.vaadin.ui.VerticalLayout; +import com.vaadin.v7.ui.ComboBox; +import de.symeda.sormas.api.EntityRelevanceStatus; +import de.symeda.sormas.api.FacadeProvider; +import de.symeda.sormas.api.common.CoreEntityType; +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; import de.symeda.sormas.api.immunization.ImmunizationCriteria; import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.ui.ControllerProvider; @@ -12,6 +27,8 @@ import de.symeda.sormas.ui.immunization.components.layout.directory.FilterFormLayout; import de.symeda.sormas.ui.immunization.components.layout.directory.ImmunizationDataLayout; import de.symeda.sormas.ui.utils.AbstractView; +import de.symeda.sormas.ui.utils.ComboBoxHelper; +import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.components.expandablebutton.ExpandableButton; public class ImmunizationsView extends AbstractView { @@ -23,14 +40,22 @@ public class ImmunizationsView extends AbstractView { private FilterFormLayout filterFormLayout; private final ImmunizationDataLayout immunizationDataLayout; + // Filters + private Label relevanceStatusInfoLabel; + private ComboBox relevanceStatusFilter; + public ImmunizationsView() { super(VIEW_NAME); criteria = ViewModelProviders.of(ImmunizationsView.class).get(ImmunizationCriteria.class); + if (criteria.getRelevanceStatus() == null) { + criteria.relevanceStatus(EntityRelevanceStatus.ACTIVE); + } immunizationDataLayout = new ImmunizationDataLayout(criteria); final VerticalLayout gridLayout = new VerticalLayout(); gridLayout.addComponent(createFilterBar()); + gridLayout.addComponent(createStatusFilterBar()); gridLayout.addComponent(immunizationDataLayout); gridLayout.setMargin(true); @@ -63,6 +88,10 @@ private void updateFilterComponents() { // TODO replace with Vaadin 8 databinding applyingCriteria = true; + if (relevanceStatusFilter != null) { + relevanceStatusFilter.setValue(criteria.getRelevanceStatus()); + } + filterFormLayout.setValue(criteria); applyingCriteria = false; @@ -76,11 +105,78 @@ private FilterFormLayout createFilterBar() { navigateTo(null, true); }); - filterFormLayout.addApplyHandler(clickEvent -> { immunizationDataLayout.refreshGrid(); }); return filterFormLayout; } + + public HorizontalLayout createStatusFilterBar() { + HorizontalLayout statusFilterLayout = new HorizontalLayout(); + statusFilterLayout.setSpacing(true); + statusFilterLayout.setMargin(false); + statusFilterLayout.setWidth(100, Unit.PERCENTAGE); + statusFilterLayout.addStyleName(CssStyles.VSPACE_3); + + HorizontalLayout actionButtonsLayout = new HorizontalLayout(); + actionButtonsLayout.setSpacing(true); + + // Show active/archived/all dropdown + if (Objects.nonNull(UserProvider.getCurrent()) && UserProvider.getCurrent().hasUserRight(UserRight.IMMUNIZATION_VIEW)) { + + if (FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.AUTOMATIC_ARCHIVING, CoreEntityType.IMMUNIZATION)) { + + int daysAfterTravelEntryGetsArchived = FacadeProvider.getFeatureConfigurationFacade() + .getProperty(FeatureType.AUTOMATIC_ARCHIVING, CoreEntityType.IMMUNIZATION, FeatureTypeProperty.THRESHOLD_IN_DAYS, Integer.class); + if (daysAfterTravelEntryGetsArchived > 0) { + relevanceStatusInfoLabel = new Label( + VaadinIcons.INFO_CIRCLE.getHtml() + " " + + String.format(I18nProperties.getString(Strings.infoArchivedTravelEntries), daysAfterTravelEntryGetsArchived), + ContentMode.HTML); + relevanceStatusInfoLabel.setVisible(false); + relevanceStatusInfoLabel.addStyleName(CssStyles.LABEL_VERTICAL_ALIGN_SUPER); + actionButtonsLayout.addComponent(relevanceStatusInfoLabel); + actionButtonsLayout.setComponentAlignment(relevanceStatusInfoLabel, Alignment.MIDDLE_RIGHT); + } + } + relevanceStatusFilter = ComboBoxHelper.createComboBoxV7(); + relevanceStatusFilter.setId("relevanceStatus"); + relevanceStatusFilter.setWidth(260, Unit.PIXELS); + relevanceStatusFilter.setNullSelectionAllowed(false); + relevanceStatusFilter.setTextInputAllowed(false); + relevanceStatusFilter.addItems((Object[]) EntityRelevanceStatus.values()); + relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE, I18nProperties.getCaption(Captions.immunizationActiveImmunizations)); + relevanceStatusFilter + .setItemCaption(EntityRelevanceStatus.ARCHIVED, I18nProperties.getCaption(Captions.immunizationArchivedImmunizations)); + relevanceStatusFilter.setItemCaption( + EntityRelevanceStatus.ACTIVE_AND_ARCHIVED, + I18nProperties.getCaption(Captions.immunizationAllActiveAndArchivedImmunizations)); + relevanceStatusFilter.setCaption(""); + + if (UserProvider.getCurrent().hasUserRight(UserRight.IMMUNIZATION_DELETE)) { + relevanceStatusFilter + .setItemCaption(EntityRelevanceStatus.DELETED, I18nProperties.getCaption(Captions.immunizationDeletedImmunizations)); + } else { + relevanceStatusFilter.removeItem(EntityRelevanceStatus.DELETED); + } + + relevanceStatusFilter.addValueChangeListener(e -> { + if (relevanceStatusInfoLabel != null) { + relevanceStatusInfoLabel.setVisible(EntityRelevanceStatus.ARCHIVED.equals(e.getProperty().getValue())); + } + criteria.relevanceStatus((EntityRelevanceStatus) e.getProperty().getValue()); + navigateTo(criteria); + }); + actionButtonsLayout.addComponent(relevanceStatusFilter); + } + + if (actionButtonsLayout.getComponentCount() > 0) { + statusFilterLayout.addComponent(actionButtonsLayout); + statusFilterLayout.setComponentAlignment(actionButtonsLayout, Alignment.TOP_RIGHT); + statusFilterLayout.setExpandRatio(actionButtonsLayout, 1); + } + + return statusFilterLayout; + } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/components/grid/ImmunizationGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/components/grid/ImmunizationGrid.java index 9e9e01f05f4..fe40dabaf03 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/components/grid/ImmunizationGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/components/grid/ImmunizationGrid.java @@ -11,6 +11,7 @@ import de.symeda.sormas.api.FacadeProvider; import de.symeda.sormas.api.caze.AgeAndBirthDateDto; 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.immunization.ImmunizationCriteria; import de.symeda.sormas.api.immunization.ImmunizationIndexDto; @@ -32,6 +33,18 @@ public ImmunizationGrid(ImmunizationCriteria criteria) { setSizeFull(); setLazyDataProvider(); setCriteria(criteria); + + Column deleteColumn = addColumn(entry -> { + if (entry.getDeletionReason() != null) { + return entry.getDeletionReason() + (entry.getOtherDeletionReason() != null ? ": " + entry.getOtherDeletionReason() : ""); + } else { + return "-"; + } + }); + deleteColumn.setId(DELETE_REASON_COLUMN); + deleteColumn.setSortable(false); + deleteColumn.setCaption(I18nProperties.getCaption(Captions.deletionReason)); + initColumns(); addItemClickListener(new ShowDetailsListener<>(ImmunizationIndexDto.PERSON_UUID, e -> { if (FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.PERSON_MANAGEMENT)) { @@ -66,7 +79,8 @@ private void initColumns() { ImmunizationIndexDto.START_DATE, ImmunizationIndexDto.END_DATE, ImmunizationIndexDto.LAST_VACCINE_TYPE, - ImmunizationIndexDto.RECOVERY_DATE); + ImmunizationIndexDto.RECOVERY_DATE, + DELETE_REASON_COLUMN); ((Column) getColumn(ImmunizationIndexDto.UUID)).setRenderer(new UuidRenderer()); ((Column) getColumn(ImmunizationIndexDto.PERSON_UUID)).setRenderer(new UuidRenderer()); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleGrid.java index bf617545dcb..da6b7748b2a 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleGrid.java @@ -112,6 +112,17 @@ public SampleGrid(SampleCriteria criteria) { lastPathogenTestColumn.setId(LAST_PATHOGEN_TEST); lastPathogenTestColumn.setSortable(false); + Column deleteColumn = addColumn(entry -> { + if (entry.getDeletionReason() != null) { + return entry.getDeletionReason() + (entry.getOtherDeletionReason() != null ? ": " + entry.getOtherDeletionReason() : ""); + } else { + return "-"; + } + }); + deleteColumn.setId(DELETE_REASON_COLUMN); + deleteColumn.setSortable(false); + deleteColumn.setCaption(I18nProperties.getCaption(Captions.deletionReason)); + setColumns( SampleIndexDto.UUID, SampleIndexDto.LAB_SAMPLE_ID, @@ -131,7 +142,8 @@ public SampleGrid(SampleCriteria criteria) { PATHOGEN_TEST_RESULT, SampleIndexDto.ADDITIONAL_TESTING_STATUS, LAST_PATHOGEN_TEST, - SampleIndexDto.PATHOGEN_TEST_COUNT); + SampleIndexDto.PATHOGEN_TEST_COUNT, + DELETE_REASON_COLUMN); ((Column) getColumn(SampleIndexDto.SHIPMENT_DATE)).setRenderer(new DateRenderer(DateFormatHelper.getDateFormat())); ((Column) getColumn(SampleIndexDto.RECEIVED_DATE)).setRenderer(new DateRenderer(DateFormatHelper.getDateFormat())); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleGridComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleGridComponent.java index bff56f075c8..fc5b6e1f26f 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleGridComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleGridComponent.java @@ -160,12 +160,20 @@ public HorizontalLayout createShipmentFilterBar() { if (UserProvider.getCurrent().hasUserRight(UserRight.SAMPLE_VIEW)) { relevanceStatusFilter = ComboBoxHelper.createComboBoxV7(); relevanceStatusFilter.setId("relevanceStatusFilter"); - relevanceStatusFilter.setWidth(140, Unit.PERCENTAGE); + relevanceStatusFilter.setWidth(220, Unit.PIXELS); relevanceStatusFilter.setNullSelectionAllowed(false); relevanceStatusFilter.addItems((Object[]) EntityRelevanceStatus.values()); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE, I18nProperties.getCaption(Captions.sampleActiveSamples)); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ARCHIVED, I18nProperties.getCaption(Captions.sampleArchivedSamples)); - relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ALL, I18nProperties.getCaption(Captions.sampleAllSamples)); + relevanceStatusFilter + .setItemCaption(EntityRelevanceStatus.ACTIVE_AND_ARCHIVED, I18nProperties.getCaption(Captions.sampleAllActiveAndArchivedSamples)); + + if (UserProvider.getCurrent().hasUserRight(UserRight.SAMPLE_DELETE)) { + relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.DELETED, I18nProperties.getCaption(Captions.sampleDeletedSamples)); + } else { + relevanceStatusFilter.removeItem(EntityRelevanceStatus.DELETED); + } + relevanceStatusFilter.addValueChangeListener(e -> { criteria.relevanceStatus((EntityRelevanceStatus) e.getProperty().getValue()); samplesView.navigateTo(criteria); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskGridComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskGridComponent.java index 36234d9972b..61248e3c66b 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskGridComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskGridComponent.java @@ -157,10 +157,10 @@ public HorizontalLayout createAssigneeFilterBar() { relevanceStatusFilter.setId("relevanceStatusFilter"); relevanceStatusFilter.setWidth(140, Unit.PERCENTAGE); relevanceStatusFilter.setNullSelectionAllowed(false); - relevanceStatusFilter.addItems((Object[]) EntityRelevanceStatus.values()); + relevanceStatusFilter.addItems(EntityRelevanceStatus.getAllExceptDeleted()); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE, I18nProperties.getCaption(Captions.taskActiveTasks)); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ARCHIVED, I18nProperties.getCaption(Captions.taskArchivedTasks)); - relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ALL, I18nProperties.getCaption(Captions.taskAllTasks)); + relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE_AND_ARCHIVED, I18nProperties.getCaption(Captions.taskAllTasks)); relevanceStatusFilter.addValueChangeListener(e -> { criteria.relevanceStatus((EntityRelevanceStatus) e.getProperty().getValue()); tasksView.navigateTo(criteria); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntriesView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntriesView.java index e3c89801194..a121ddc438b 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntriesView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntriesView.java @@ -97,16 +97,15 @@ public TravelEntriesView() { } } - if (UserProvider.getCurrent().hasUserRight(UserRight.TRAVEL_ENTRY_DELETE) - && UserProvider.getCurrent().hasUserRight(UserRight.PERFORM_BULK_OPERATIONS)) { + && UserProvider.getCurrent().hasUserRight(UserRight.PERFORM_BULK_OPERATIONS)) { Button btnEnterBulkEditMode = ButtonHelper.createIconButton(Captions.actionEnterBulkEditMode, VaadinIcons.CHECK_SQUARE_O, null); btnEnterBulkEditMode.setVisible(!viewConfiguration.isInEagerMode()); addHeaderComponent(btnEnterBulkEditMode); Button btnLeaveBulkEditMode = - ButtonHelper.createIconButton(Captions.actionLeaveBulkEditMode, VaadinIcons.CLOSE, null, ValoTheme.BUTTON_PRIMARY); + ButtonHelper.createIconButton(Captions.actionLeaveBulkEditMode, VaadinIcons.CLOSE, null, ValoTheme.BUTTON_PRIMARY); btnLeaveBulkEditMode.setVisible(viewConfiguration.isInEagerMode()); addHeaderComponent(btnLeaveBulkEditMode); @@ -196,16 +195,12 @@ public HorizontalLayout createStatusFilterBar() { if (FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.AUTOMATIC_ARCHIVING, CoreEntityType.TRAVEL_ENTRY)) { int daysAfterTravelEntryGetsArchived = FacadeProvider.getFeatureConfigurationFacade() - .getProperty( - FeatureType.AUTOMATIC_ARCHIVING, - CoreEntityType.TRAVEL_ENTRY, - FeatureTypeProperty.THRESHOLD_IN_DAYS, - Integer.class); + .getProperty(FeatureType.AUTOMATIC_ARCHIVING, CoreEntityType.TRAVEL_ENTRY, FeatureTypeProperty.THRESHOLD_IN_DAYS, Integer.class); if (daysAfterTravelEntryGetsArchived > 0) { relevanceStatusInfoLabel = new Label( - VaadinIcons.INFO_CIRCLE.getHtml() + " " - + String.format(I18nProperties.getString(Strings.infoArchivedTravelEntries), daysAfterTravelEntryGetsArchived), - ContentMode.HTML); + VaadinIcons.INFO_CIRCLE.getHtml() + " " + + String.format(I18nProperties.getString(Strings.infoArchivedTravelEntries), daysAfterTravelEntryGetsArchived), + ContentMode.HTML); relevanceStatusInfoLabel.setVisible(false); relevanceStatusInfoLabel.addStyleName(CssStyles.LABEL_VERTICAL_ALIGN_SUPER); actionButtonsLayout.addComponent(relevanceStatusInfoLabel); @@ -214,15 +209,25 @@ public HorizontalLayout createStatusFilterBar() { } relevanceStatusFilter = ComboBoxHelper.createComboBoxV7(); relevanceStatusFilter.setId("relevanceStatus"); - relevanceStatusFilter.setWidth(140, Unit.PIXELS); + relevanceStatusFilter.setWidth(250, Unit.PIXELS); relevanceStatusFilter.setNullSelectionAllowed(false); relevanceStatusFilter.setTextInputAllowed(false); relevanceStatusFilter.addItems((Object[]) EntityRelevanceStatus.values()); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE, I18nProperties.getCaption(Captions.travelEntryActiveTravelEntries)); relevanceStatusFilter .setItemCaption(EntityRelevanceStatus.ARCHIVED, I18nProperties.getCaption(Captions.travelEntryArchivedTravelEntries)); - relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ALL, I18nProperties.getCaption(Captions.travelEntryAllTravelEntries)); + relevanceStatusFilter.setItemCaption( + EntityRelevanceStatus.ACTIVE_AND_ARCHIVED, + I18nProperties.getCaption(Captions.travelEntryAllActiveAndArchivedTravelEntries)); relevanceStatusFilter.setCaption(""); + + if (UserProvider.getCurrent().hasUserRight(UserRight.TRAVEL_ENTRY_DELETE)) { + relevanceStatusFilter + .setItemCaption(EntityRelevanceStatus.DELETED, I18nProperties.getCaption(Captions.TravelEntry_deletedTravelEntries)); + } else { + relevanceStatusFilter.removeItem(EntityRelevanceStatus.DELETED); + } + relevanceStatusFilter.addValueChangeListener(e -> { if (relevanceStatusInfoLabel != null) { relevanceStatusInfoLabel.setVisible(EntityRelevanceStatus.ARCHIVED.equals(e.getProperty().getValue())); @@ -235,15 +240,15 @@ public HorizontalLayout createStatusFilterBar() { // Bulk operation dropdown if (UserProvider.getCurrent().hasUserRight(UserRight.TRAVEL_ENTRY_DELETE) - && UserProvider.getCurrent().hasUserRight(UserRight.PERFORM_BULK_OPERATIONS)) { + && UserProvider.getCurrent().hasUserRight(UserRight.PERFORM_BULK_OPERATIONS)) { List bulkActions = new ArrayList<>(); bulkActions.add( - new MenuBarHelper.MenuBarItem( - I18nProperties.getCaption(Captions.bulkDelete), - VaadinIcons.TRASH, - mi -> grid.bulkActionHandler( - items -> ControllerProvider.getTravelEntryController().deleteAllSelectedItems(items, () -> navigateTo(criteria)), - true))); + new MenuBarHelper.MenuBarItem( + I18nProperties.getCaption(Captions.bulkDelete), + VaadinIcons.TRASH, + mi -> grid.bulkActionHandler( + items -> ControllerProvider.getTravelEntryController().deleteAllSelectedItems(items, () -> navigateTo(criteria)), + true))); bulkOperationsDropdown = MenuBarHelper.createDropDown(Captions.bulkActions, bulkActions); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryGrid.java index 82a34fa5e93..0dc0a6ea66b 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryGrid.java @@ -9,6 +9,7 @@ import com.vaadin.ui.renderers.DateRenderer; import de.symeda.sormas.api.FacadeProvider; +import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.person.PersonDto; import de.symeda.sormas.api.travelentry.TravelEntryCriteria; @@ -42,6 +43,17 @@ public TravelEntryGrid(TravelEntryCriteria criteria) { setCriteria(criteria); } + Column deleteColumn = addColumn(entry -> { + if (entry.getDeletionReason() != null) { + return entry.getDeletionReason() + (entry.getOtherDeletionReason() != null ? ": " + entry.getOtherDeletionReason() : ""); + } else { + return "-"; + } + }); + deleteColumn.setId(DELETE_REASON_COLUMN); + deleteColumn.setSortable(false); + deleteColumn.setCaption(I18nProperties.getCaption(Captions.deletionReason)); + setCriteria(criteria); initColumns(); addItemClickListener( @@ -61,7 +73,8 @@ private void initColumns() { TravelEntryIndexDto.RECOVERED, TravelEntryIndexDto.VACCINATED, TravelEntryIndexDto.TESTED_NEGATIVE, - TravelEntryIndexDto.QUARANTINE_TO); + TravelEntryIndexDto.QUARANTINE_TO, + DELETE_REASON_COLUMN); ((Column) getColumn(TravelEntryIndexDto.UUID)).setRenderer(new UuidRenderer()); ((Column) getColumn(TravelEntryIndexDto.RECOVERED)).setRenderer(new BooleanRenderer()); @@ -95,10 +108,9 @@ public void setLazyDataProvider() { setSelectionMode(SelectionMode.NONE); } - public void setEagerDataProvider() { ListDataProvider dataProvider = - DataProvider.fromStream(FacadeProvider.getTravelEntryFacade().getIndexList(getCriteria(), null, null, null).stream()); + DataProvider.fromStream(FacadeProvider.getTravelEntryFacade().getIndexList(getCriteria(), null, null, null).stream()); setDataProvider(dataProvider); setSelectionMode(SelectionMode.MULTI); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FilteredGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FilteredGrid.java index c35317537af..43864a11462 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FilteredGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FilteredGrid.java @@ -25,6 +25,7 @@ public class FilteredGrid extends Grid { public static final String ACTION_BTN_ID = "action"; + public static final String DELETE_REASON_COLUMN = "deleteReasonCumulated"; private static final long serialVersionUID = 8116377533153377424L; @@ -147,7 +148,7 @@ private void addActionColumnConfiguration(Consumer handler, boolean isEditAct Column editColumn = addColumn(entry -> isEditAction ? VaadinIcons.EDIT.getHtml() : VaadinIcons.EYE.getHtml(), new HtmlRenderer()); editColumn.setId(ACTION_BTN_ID); - editColumn.setCaption(isEditAction? I18nProperties.getCaption(Captions.edit): I18nProperties.getCaption(Captions.view)); + editColumn.setCaption(isEditAction ? I18nProperties.getCaption(Captions.edit) : I18nProperties.getCaption(Captions.view)); editColumn.setSortable(false); editColumn.setWidth(20); From 0d6ccc32787d5a43adb5076ee0d91466a822810e Mon Sep 17 00:00:00 2001 From: dinua Date: Wed, 14 Dec 2022 11:57:13 +0200 Subject: [PATCH 012/166] #9360 refactor after code review , add method if exist poe for case --- .../pointofentry/PointOfEntryFacade.java | 2 ++ .../pointofentry/PointOfEntryFacadeEjb.java | 15 +++++++++++++ .../PointOfEntryFacadeEjbTest.java | 22 +++++++++++++++++++ .../symeda/sormas/ui/caze/CaseController.java | 5 ++--- 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/infrastructure/pointofentry/PointOfEntryFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/infrastructure/pointofentry/PointOfEntryFacade.java index dff2d64ce9d..f97ac7d60b8 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/infrastructure/pointofentry/PointOfEntryFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/infrastructure/pointofentry/PointOfEntryFacade.java @@ -27,4 +27,6 @@ public interface PointOfEntryFacade extends InfrastructureFacade pointOfEntryUuids); PointOfEntryDto getByCaseUuid(String caseUuid); + + boolean existForCase(String caseUuid); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryFacadeEjb.java index 482c7e9584e..d6de0b9cd29 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryFacadeEjb.java @@ -237,6 +237,21 @@ public PointOfEntryDto getByCaseUuid(String caseUuid) { return QueryHelper.getSingleResult(em, cq, this::toDto); } + @Override + public boolean existForCase(String caseUuid) { + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(Boolean.class); + Root root = cq.from(Case.class); + CaseJoins caseCaseJoins = new CaseJoins(root); + Join pointOfEntryJoin = caseCaseJoins.getPointOfEntry(); + + cq.select(cb.literal(true)); + cq.where(cb.and(cb.equal(root.get(Case.UUID), caseUuid), cb.isNotNull(pointOfEntryJoin.get(PointOfEntry.ID)))); + + Boolean exist = QueryHelper.getSingleResult(em, cq); + return Boolean.TRUE.equals(exist); + } + @Override public boolean hasArchivedParentInfrastructure(Collection pointOfEntryUuids) { diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PointOfEntryFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PointOfEntryFacadeEjbTest.java index f6a714d57f1..0e02bcc0d57 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PointOfEntryFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PointOfEntryFacadeEjbTest.java @@ -1,8 +1,10 @@ package de.symeda.sormas.backend.infrastructure; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Date; import java.util.List; @@ -93,4 +95,24 @@ public void testGetPointOfEntryByCaseUuid() { assertEquals(rdcf.pointOfEntry.getUuid(), pointOfEntryDto.getUuid()); } + @Test + public void testExistForCase() { + RDCF rdcf = creator.createRDCF(); + UserDto user = creator.createUser(rdcf, creator.getUserRoleReference(DefaultUserRole.NATIONAL_USER)); + PersonDto personDto = creator.createPerson("John", "Doe"); + + CaseDataDto case1 = creator.createCase(user.toReference(), personDto.toReference(), rdcf); + CaseDataDto case2 = creator.createCase(user.toReference(), rdcf, c -> { + c.setPerson(personDto.toReference()); + c.setPointOfEntry(rdcf.pointOfEntry); + }); + + case1.setPointOfEntry(null); + getCaseFacade().save(case1); + + boolean existPoeForCase = getPointOfEntryFacade().existForCase(case1.getUuid()); + assertFalse(existPoeForCase); + existPoeForCase = getPointOfEntryFacade().existForCase(case2.getUuid()); + assertTrue(existPoeForCase); + } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java index 87e3c4d7864..0cbdaa9f9a2 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java @@ -1346,7 +1346,7 @@ public CommitDiscardWrapperComponent getPortHealthInfoCompon return null; } - PointOfEntryDto pointOfEntry = FacadeProvider.getPointOfEntryFacade().getByCaseUuid(caseUuid);// getByUuid(casePointOfEntry.getUuid()); + PointOfEntryDto pointOfEntry = FacadeProvider.getPointOfEntryFacade().getByCaseUuid(caseUuid); PortHealthInfoForm form = new PortHealthInfoForm(pointOfEntry, caze.getPointOfEntryDetails()); form.setValue(getPortHealthInfo(caze)); @@ -1849,8 +1849,7 @@ private static class JurisdictionValues { public boolean hasPointOfEntry(CaseDataDto caze) { if (caze.getPointOfEntry() == null) { - PointOfEntryDto pointOfEntryDto = FacadeProvider.getPointOfEntryFacade().getByCaseUuid(caze.getUuid()); - return pointOfEntryDto != null; + return FacadeProvider.getPointOfEntryFacade().existForCase(caze.getUuid()); } return true; } From 9fbdead8c04e3577bb72f4c51768c3f3b809c93f Mon Sep 17 00:00:00 2001 From: dinua Date: Wed, 14 Dec 2022 13:26:26 +0200 Subject: [PATCH 013/166] #9360 fix test --- .../api/infrastructure/pointofentry/PointOfEntryFacade.java | 2 +- .../infrastructure/pointofentry/PointOfEntryFacadeEjb.java | 2 +- .../backend/infrastructure/PointOfEntryFacadeEjbTest.java | 4 ++-- .../main/java/de/symeda/sormas/ui/caze/CaseController.java | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/infrastructure/pointofentry/PointOfEntryFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/infrastructure/pointofentry/PointOfEntryFacade.java index f97ac7d60b8..fcd967f1101 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/infrastructure/pointofentry/PointOfEntryFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/infrastructure/pointofentry/PointOfEntryFacade.java @@ -28,5 +28,5 @@ public interface PointOfEntryFacade extends InfrastructureFacade cq = cb.createQuery(Boolean.class); Root root = cq.from(Case.class); diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PointOfEntryFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PointOfEntryFacadeEjbTest.java index 0e02bcc0d57..2ed37a872ba 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PointOfEntryFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PointOfEntryFacadeEjbTest.java @@ -110,9 +110,9 @@ public void testExistForCase() { case1.setPointOfEntry(null); getCaseFacade().save(case1); - boolean existPoeForCase = getPointOfEntryFacade().existForCase(case1.getUuid()); + boolean existPoeForCase = getPointOfEntryFacade().existsForCase(case1.getUuid()); assertFalse(existPoeForCase); - existPoeForCase = getPointOfEntryFacade().existForCase(case2.getUuid()); + existPoeForCase = getPointOfEntryFacade().existsForCase(case2.getUuid()); assertTrue(existPoeForCase); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java index 0cbdaa9f9a2..51cad02e8fb 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java @@ -1849,7 +1849,7 @@ private static class JurisdictionValues { public boolean hasPointOfEntry(CaseDataDto caze) { if (caze.getPointOfEntry() == null) { - return FacadeProvider.getPointOfEntryFacade().existForCase(caze.getUuid()); + return FacadeProvider.getPointOfEntryFacade().existsForCase(caze.getUuid()); } return true; } From 09b3b2699886c691f0060562c2b19ff6c641e8da Mon Sep 17 00:00:00 2001 From: Bal Andrei Date: Fri, 16 Dec 2022 12:12:24 +0200 Subject: [PATCH 014/166] #7305 Add synchronization filter to user filter --- .../sormas/api/feature/FeatureType.java | 2 +- .../api/feature/FeatureTypeProperty.java | 2 +- .../sormas/backend/action/ActionService.java | 16 ++- .../backend/campaign/CampaignService.java | 5 + .../data/CampaignFormDataService.java | 5 + .../CampaignDiagramDefinitionService.java | 5 + .../form/CampaignFormMetaService.java | 5 + .../sormas/backend/caze/CaseService.java | 36 +++++- .../SurveillanceReportService.java | 5 + .../clinicalcourse/ClinicalVisitService.java | 7 ++ .../AbstractInfrastructureAdoService.java | 5 + ...oServiceWithUserFilterAndJurisdiction.java | 14 ++- .../backend/contact/ContactService.java | 46 ++++++- .../CustomizableEnumValueService.java | 5 + .../disease/DiseaseConfigurationService.java | 5 + .../backend/document/DocumentService.java | 5 + .../backend/event/EventGroupService.java | 5 + .../event/EventParticipantService.java | 26 +++- .../sormas/backend/event/EventService.java | 36 +++++- .../ExternalMessageService.java | 5 + .../feature/FeatureConfigurationService.java | 5 + .../DirectoryImmunizationService.java | 5 + .../immunization/ImmunizationService.java | 5 + .../infrastructure/PopulationDataService.java | 5 + .../backend/outbreak/OutbreakService.java | 5 + .../sormas/backend/person/PersonService.java | 5 + .../report/AggregateReportService.java | 5 + .../report/WeeklyReportEntryService.java | 5 + .../backend/report/WeeklyReportService.java | 5 + .../backend/sample/AdditionalTestService.java | 5 + .../backend/sample/PathogenTestService.java | 5 + .../sormas/backend/sample/SampleService.java | 76 +++++++++--- .../share/ExternalShareInfoService.java | 5 + .../SormasToSormasOriginInfoService.java | 5 + .../SormasToSormasShareRequestService.java | 5 + .../outgoing/ShareRequestInfoService.java | 5 + .../SormasToSormasShareInfoService.java | 6 + .../sormas/backend/task/TaskService.java | 117 ++++++++++++++---- .../backend/therapy/PrescriptionService.java | 7 ++ .../backend/therapy/TreatmentService.java | 6 + .../services/BaseTravelEntryService.java | 5 + .../sormas/backend/user/UserRoleService.java | 5 + .../sormas/backend/user/UserService.java | 6 + .../vaccination/VaccinationService.java | 5 + .../sormas/backend/visit/VisitService.java | 5 + .../caze/CaseFacadeEjbUserFilterTest.java | 2 +- 46 files changed, 489 insertions(+), 66 deletions(-) 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 97d7bebbb54..adae12b2924 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 @@ -72,7 +72,7 @@ public enum FeatureType { TRAVEL_ENTRIES(true, false, null, null, null), DASHBOARD(true, true, null, null, null), - LIMITED_SYNCHRONIZATION(true, false, null, null, ImmutableMap.of(FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES, Boolean.FALSE, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, -1)), + LIMITED_SYNCHRONIZATION(true, false, null, null, ImmutableMap.of(FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES, Boolean.FALSE, FeatureTypeProperty.MAX_CHANGE_DATE_PERIOD, -1)), // FEATURE EXTENSIONS ASSIGN_TASKS_TO_HIGHER_LEVEL(true, 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 5e50f4460ad..b7556f8f684 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 @@ -23,7 +23,7 @@ public enum FeatureTypeProperty { ALLOW_FREE_EDITING(Boolean.class), THRESHOLD_IN_DAYS(Integer.class), EXCLUDE_NO_CASE_CLASSIFIED_CASES(Boolean.class), - MAX_CHANGE_DATE_SYNCHRONIZATION(Integer.class), + MAX_CHANGE_DATE_PERIOD(Integer.class), S2S_SHARING(Boolean.class), SHARE_ASSOCIATED_CONTACTS(Boolean.class), SHARE_SAMPLES(Boolean.class), diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/action/ActionService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/action/ActionService.java index 300b178445b..5c884114f05 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/action/ActionService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/action/ActionService.java @@ -126,7 +126,15 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return createUserFilter(new ActionQueryContext(cb, cq, from), true); + } + public Predicate createUserFilter(ActionQueryContext queryContext) { + return createUserFilter(queryContext, false); + } + public Predicate createUserFilter(ActionQueryContext queryContext, boolean obsolete) { CriteriaQuery cq = queryContext.getQuery(); CriteriaBuilder cb = queryContext.getCriteriaBuilder(); @@ -143,8 +151,12 @@ public Predicate createUserFilter(ActionQueryContext queryContext) { } Predicate filter = cb.equal(joins.getCreator(), currentUser); - - Predicate eventFilter = eventService.createUserFilter(new EventQueryContext(cb, cq, joins.getEventJoins())); + Predicate eventFilter; + if (obsolete) { + eventFilter = eventService.createUserFilterForObsoleteSync(new EventQueryContext(cb, cq, joins.getEventJoins())); + } else { + eventFilter = eventService.createUserFilter(new EventQueryContext(cb, cq, joins.getEventJoins())); + } if (eventFilter != null) { filter = cb.or(filter, eventFilter); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java index 89e4b044a8f..fc0e6641934 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java @@ -46,6 +46,11 @@ public Predicate createUserFilter(CampaignQueryContext queryContext) { return null; } + @Override + public Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + public Predicate buildCriteriaFilter(CampaignQueryContext queryContext, CampaignCriteria campaignCriteria) { CriteriaBuilder cb = queryContext.getCriteriaBuilder(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/data/CampaignFormDataService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/data/CampaignFormDataService.java index daf64ecb154..f2e2c2e69e4 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/data/CampaignFormDataService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/data/CampaignFormDataService.java @@ -130,6 +130,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return createUserFilter(cb, cq, from); + } + @Override protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/diagram/CampaignDiagramDefinitionService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/diagram/CampaignDiagramDefinitionService.java index 4ff47e3995e..1f82c63d1f6 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/diagram/CampaignDiagramDefinitionService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/diagram/CampaignDiagramDefinitionService.java @@ -26,6 +26,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + @Override protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/form/CampaignFormMetaService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/form/CampaignFormMetaService.java index d52ef82a01c..4bdecfc9d4b 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/form/CampaignFormMetaService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/form/CampaignFormMetaService.java @@ -29,6 +29,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + @Override protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; 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 2c0325d80f0..afb6714ed3f 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 @@ -608,7 +608,7 @@ public Predicate createObsoleteLimitedSyncCasePredicate(CriteriaBuilder cb, From @Override protected Predicate getUserFilterForObsoleteUuids(CriteriaBuilder cb, CriteriaQuery cq, Root from) { - return createUserFilter(new CaseQueryContext(cb, cq, from), new CaseUserFilterCriteria().excludeLimitedSyncRestrictions(true)); + return createUserFilterForObsoleteSync(new CaseQueryContext(cb, cq, from), new CaseUserFilterCriteria().excludeLimitedSyncRestrictions(true)); } /** @@ -1303,12 +1303,29 @@ protected Predicate createUserFilterInternal(CriteriaBuilder cb, CriteriaQuery c return createUserFilter(new CaseQueryContext(cb, cq, from)); } + @Override + public Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return createUserFilterForObsoleteSync(new CaseQueryContext(cb, cq, from)); + } + public Predicate createUserFilter(CaseQueryContext caseQueryContext) { return createUserFilter(caseQueryContext, null); } - @SuppressWarnings("rawtypes") + public Predicate createUserFilterForObsoleteSync(CaseQueryContext caseQueryContext) { + return createUserFilter(caseQueryContext, null, true); + } + public Predicate createUserFilter(CaseQueryContext caseQueryContext, CaseUserFilterCriteria userFilterCriteria) { + return createUserFilter(caseQueryContext, userFilterCriteria, false); + } + + public Predicate createUserFilterForObsoleteSync(CaseQueryContext caseQueryContext, CaseUserFilterCriteria userFilterCriteria) { + return createUserFilter(caseQueryContext, userFilterCriteria, true); + } + + @SuppressWarnings("rawtypes") + public Predicate createUserFilter(CaseQueryContext caseQueryContext, CaseUserFilterCriteria userFilterCriteria, boolean obsolete) { User currentUser = getCurrentUser(); if (currentUser == null) { @@ -1436,6 +1453,21 @@ public Predicate createUserFilter(CaseQueryContext caseQueryContext, CaseUserFil filter = CriteriaBuilderHelper.and(cb, filter, limitedCaseSyncPredicate); } + if (RequestContextHolder.isMobileSync()) { + if (obsolete) { + Predicate limitedChangeDateForObsoletePredicate = + CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilterForObsoleteEntities(cb, casePath)); + if (limitedChangeDateForObsoletePredicate != null) { + filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDateForObsoletePredicate); + } + } else { + Predicate limitedChangeDatePredicate = CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilter(cb, casePath)); + if (limitedChangeDatePredicate != null) { + filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDatePredicate); + } + } + } + return filter; } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportService.java index 82214f1d8c1..3ae08c54769 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportService.java @@ -83,6 +83,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + @Override protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java index 2668495ce57..1efcd3cecda 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java @@ -147,6 +147,13 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + Join clinicalCourse = from.join(ClinicalVisit.CLINICAL_COURSE, JoinType.LEFT); + return caseService + .createUserFilterForObsoleteSync(new CaseQueryContext(cb, cq, new CaseJoins(clinicalCourse.join(ClinicalCourse.CASE, JoinType.LEFT)))); + } + @Override public boolean inJurisdictionOrOwned(ClinicalVisit entity) { return fulfillsCondition(entity, this::inJurisdictionOrOwned); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractInfrastructureAdoService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractInfrastructureAdoService.java index 5cb711ee55c..061f5817802 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractInfrastructureAdoService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractInfrastructureAdoService.java @@ -33,6 +33,11 @@ public Predicate createBasicFilter(CriteriaBuilder cb, Root root) { return cb.isFalse(root.get(InfrastructureAdo.ARCHIVED)); } + @Override + public Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + @Override protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java index 6015eb61a99..0923b173490 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java @@ -44,9 +44,11 @@ protected AdoServiceWithUserFilterAndJurisdiction(Class elementClass) { @SuppressWarnings("rawtypes") public abstract Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from); + public abstract Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from); + protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_PERIOD, Integer.class); if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Date maxChangeDate = DateHelper.subtractDays(new Date(), maxChangeDatePeriod); @@ -58,12 +60,12 @@ protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, Integer.class); + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_PERIOD, Integer.class); if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { Date maxChangeDate = DateHelper.subtractDays(new Date(), maxChangeDatePeriod); Timestamp timestamp = Timestamp.from(DateHelper.getStartOfDay(maxChangeDate).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.lessThan(from.get(ADO.CHANGE_DATE), timestamp)); + return CriteriaBuilderHelper.or(cb, cb.lessThan(from.get(ADO.CHANGE_DATE), timestamp)); } return null; } @@ -192,7 +194,11 @@ public List getObsoleteUuidsSince(Date since) { } protected Predicate getUserFilterForObsoleteUuids(CriteriaBuilder cb, CriteriaQuery cq, Root from) { - return createUserFilter(cb, cq, from); + if (RequestContextHolder.isMobileSync()) { + return createUserFilterForObsoleteSync(cb, cq, from); + } else { + return createUserFilter(cb, cq, from); + } } protected List getAdditionalObsoleteUuidsPredicates(Date since, CriteriaBuilder cb, CriteriaQuery cq, Root from) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java index 25f7f121064..d09fe52949f 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java @@ -505,7 +505,7 @@ protected List getAdditionalObsoleteUuidsPredicates(Date since, Crite @Override protected Predicate getUserFilterForObsoleteUuids(CriteriaBuilder cb, CriteriaQuery cq, Root from) { - return createUserFilter(new ContactQueryContext(cb, cq, from), new ContactCriteria().excludeLimitedSyncRestrictions(true)); + return createUserFilterForObsoleteSync(new ContactQueryContext(cb, cq, from), new ContactCriteria().excludeLimitedSyncRestrictions(true)); } public Long countContactsForMap(Region region, District district, Disease disease, Date from, Date to) { @@ -1004,11 +1004,28 @@ protected Predicate createUserFilterInternal(CriteriaBuilder cb, CriteriaQuery c return createUserFilter(new ContactQueryContext(cb, cq, from)); } + @Override + public Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return createUserFilterForObsoleteSync(new ContactQueryContext(cb, cq, from)); + } + public Predicate createUserFilter(ContactQueryContext queryContext) { return createUserFilter(queryContext, null); } + public Predicate createUserFilterForObsoleteSync(ContactQueryContext queryContext) { + return createUserFilter(queryContext, null, true); + } + public Predicate createUserFilter(ContactQueryContext contactQueryContext, ContactCriteria contactCriteria) { + return createUserFilter(contactQueryContext, contactCriteria, false); + } + + public Predicate createUserFilterForObsoleteSync(ContactQueryContext contactQueryContext, ContactCriteria contactCriteria) { + return createUserFilter(contactQueryContext, contactCriteria, true); + } + + public Predicate createUserFilter(ContactQueryContext contactQueryContext, ContactCriteria contactCriteria, boolean obsolete) { Predicate userFilter = null; @@ -1017,11 +1034,19 @@ public Predicate createUserFilter(ContactQueryContext contactQueryContext, Conta CaseQueryContext caseQueryContext = new CaseQueryContext(cb, cq, contactQueryContext.getJoins().getCaseJoins()); if (contactCriteria == null || contactCriteria.getIncludeContactsFromOtherJurisdictions()) { - userFilter = caseService.createUserFilter(caseQueryContext); + if (obsolete) { + userFilter = caseService.createUserFilterForObsoleteSync(caseQueryContext); + } else { + userFilter = caseService.createUserFilter(caseQueryContext); + } } else { CaseUserFilterCriteria userFilterCriteria = new CaseUserFilterCriteria().excludeLimitedSyncRestrictions(contactCriteria.isExcludeLimitedSyncRestrictions()); - userFilter = caseService.createUserFilter(caseQueryContext, userFilterCriteria); + if (obsolete) { + userFilter = caseService.createUserFilterForObsoleteSync(caseQueryContext, userFilterCriteria); + } else { + userFilter = caseService.createUserFilter(caseQueryContext, userFilterCriteria); + } } Predicate filter; @@ -1030,6 +1055,21 @@ public Predicate createUserFilter(ContactQueryContext contactQueryContext, Conta } else { filter = createUserFilterWithoutCase(contactQueryContext, contactCriteria); } + + if (RequestContextHolder.isMobileSync()) { + if (obsolete) { + Predicate limitedChangeDateForObsoletePredicate = + CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilterForObsoleteEntities(cb, contactQueryContext.getRoot())); + if (limitedChangeDateForObsoletePredicate != null) { + filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDateForObsoletePredicate); + } + } else { + Predicate limitedChangeDatePredicate = CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilter(cb, contactQueryContext.getRoot())); + if (limitedChangeDatePredicate != null) { + filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDatePredicate); + } + } + } return filter; } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/customizableenum/CustomizableEnumValueService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/customizableenum/CustomizableEnumValueService.java index 04ed9445b39..1245f11ca4a 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/customizableenum/CustomizableEnumValueService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/customizableenum/CustomizableEnumValueService.java @@ -38,6 +38,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + @Override protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/disease/DiseaseConfigurationService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/disease/DiseaseConfigurationService.java index 300dc3c1808..229fc1565da 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/disease/DiseaseConfigurationService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/disease/DiseaseConfigurationService.java @@ -57,6 +57,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + @Override protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/document/DocumentService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/document/DocumentService.java index 6e9a6f5f1b6..efe439b202d 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/document/DocumentService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/document/DocumentService.java @@ -47,6 +47,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + @Override protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventGroupService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventGroupService.java index e4f4bc9decc..5d9c62cfe29 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventGroupService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventGroupService.java @@ -66,6 +66,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return createUserFilter(cb, cq, from); + } + @Override protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java index 80699d1b618..df03e882461 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java @@ -291,22 +291,42 @@ protected Predicate createUserFilterInternal(CriteriaBuilder cb, CriteriaQuery c return createUserFilter(new EventParticipantQueryContext(cb, cq, from)); } + @Override + public Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return createUserFilterForObsoleteSync(new EventParticipantQueryContext(cb, cq, from)); + } + public Predicate createUserFilter(EventParticipantQueryContext eventParticipantQueryContext) { final EventUserFilterCriteria eventUserFilterCriteria = new EventUserFilterCriteria(); eventUserFilterCriteria.includeUserCaseAndEventParticipantFilter(true); eventUserFilterCriteria.forceRegionJurisdiction(true); - return createUserFilter(eventParticipantQueryContext, eventUserFilterCriteria); + return createUserFilter(eventParticipantQueryContext, eventUserFilterCriteria, false); + } + + public Predicate createUserFilterForObsoleteSync(EventParticipantQueryContext eventParticipantQueryContext) { + final EventUserFilterCriteria eventUserFilterCriteria = new EventUserFilterCriteria(); + eventUserFilterCriteria.includeUserCaseAndEventParticipantFilter(true); + eventUserFilterCriteria.forceRegionJurisdiction(true); + + return createUserFilter(eventParticipantQueryContext, eventUserFilterCriteria, true); } public Predicate createUserFilter(EventParticipantQueryContext epqc, EventUserFilterCriteria eventUserFilterCriteria) { + return createUserFilter(epqc, eventUserFilterCriteria, false); + } + + public Predicate createUserFilter(EventParticipantQueryContext epqc, EventUserFilterCriteria eventUserFilterCriteria, boolean obsolete) { final CriteriaBuilder cb = epqc.getCriteriaBuilder(); final CriteriaQuery cq = epqc.getQuery(); final EventParticipantJoins joins = epqc.getJoins(); - - return eventService.createUserFilter(new EventQueryContext(cb, cq, joins.getEventJoins()), eventUserFilterCriteria); + if (obsolete) { + return eventService.createUserFilterForObsoleteSync(new EventQueryContext(cb, cq, joins.getEventJoins()), eventUserFilterCriteria); + } else { + return eventService.createUserFilter(new EventQueryContext(cb, cq, joins.getEventJoins()), eventUserFilterCriteria); + } } public EventParticipant getByEventAndPerson(String eventUuid, String personUuid) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java index f358d655fc4..24b53bc6e02 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java @@ -401,11 +401,28 @@ protected Predicate createUserFilterInternal(CriteriaBuilder cb, CriteriaQuery c return createUserFilter(new EventQueryContext(cb, cq, from)); } + @Override + public Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return createUserFilterForObsoleteSync(new EventQueryContext(cb, cq, from)); + } + public Predicate createUserFilter(EventQueryContext queryContext) { - return createUserFilter(queryContext, null); + return createUserFilter(queryContext, null, false); + } + + public Predicate createUserFilterForObsoleteSync(EventQueryContext queryContext) { + return createUserFilter(queryContext, null, true); + } + + public Predicate createUserFilter(EventQueryContext queryContext, EventUserFilterCriteria eventUserFilterCriteria) { + return createUserFilter(queryContext, eventUserFilterCriteria, false); + } + + public Predicate createUserFilterForObsoleteSync(EventQueryContext queryContext, EventUserFilterCriteria eventUserFilterCriteria) { + return createUserFilter(queryContext, eventUserFilterCriteria, true); } - public Predicate createUserFilter(final EventQueryContext queryContext, final EventUserFilterCriteria eventUserFilterCriteria) { + public Predicate createUserFilter(final EventQueryContext queryContext, final EventUserFilterCriteria eventUserFilterCriteria, final boolean obsolete) { User currentUser = getCurrentUser(); if (currentUser == null) { @@ -486,6 +503,21 @@ public Predicate createUserFilter(final EventQueryContext queryContext, final Ev cb.or(cb.equal(eventJoin.get(Event.DISEASE), currentUser.getLimitedDisease()), cb.isNull(eventJoin.get(Event.DISEASE)))); } + if (RequestContextHolder.isMobileSync()) { + if (obsolete) { + Predicate limitedChangeDateForObsoletePredicate = + CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilterForObsoleteEntities(cb, eventJoin)); + if (limitedChangeDateForObsoletePredicate != null) { + filter = CriteriaBuilderHelper.or(cb, filter, limitedChangeDateForObsoletePredicate); + } + } else { + Predicate limitedChangeDatePredicate = CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilter(cb, eventJoin)); + if (limitedChangeDatePredicate != null) { + filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDatePredicate); + } + } + } + return filter; } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageService.java index 55a7f39ff55..1a8e26ec8d4 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageService.java @@ -61,6 +61,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + @Override protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; 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 5fc8b545524..0d9401774f2 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 @@ -123,6 +123,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return createUserFilter(cb, cq, from); + } + @Override protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/DirectoryImmunizationService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/DirectoryImmunizationService.java index df474e805fe..e478e321945 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/DirectoryImmunizationService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/DirectoryImmunizationService.java @@ -72,6 +72,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return createUserFilter(cb, cq, from); + } + @Override protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java index ba54d949992..9fd743474ad 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java @@ -501,6 +501,11 @@ protected Predicate createUserFilterInternal(CriteriaBuilder cb, CriteriaQuery c return createUserFilter(new ImmunizationQueryContext(cb, cq, from)); } + @Override + public Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return createUserFilter(new ImmunizationQueryContext(cb, cq, from)); + } + public Predicate createUserFilter(ImmunizationQueryContext qc) { User currentUser = getCurrentUser(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/PopulationDataService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/PopulationDataService.java index e7aa7783897..84a39f91164 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/PopulationDataService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/PopulationDataService.java @@ -60,6 +60,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + @Override protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/outbreak/OutbreakService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/outbreak/OutbreakService.java index 43cd390e084..2443c68da54 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/outbreak/OutbreakService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/outbreak/OutbreakService.java @@ -170,6 +170,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + public Predicate buildCriteriaFilter(OutbreakCriteria criteria, CriteriaBuilder cb, Root from) { Predicate filter = null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java index dc996b985ee..c575f7e3c48 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java @@ -272,6 +272,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From obsolete!"); } + @Override + public Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return createUserFilter(cb, cq, from); + } + public Predicate createUserFilter(PersonQueryContext queryContext, PersonCriteria personCriteria) { /* diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java index a8d725a45a5..7040fac784d 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java @@ -119,6 +119,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return createUserFilter(cb, cq, from); + } + @SuppressWarnings("rawtypes") public Predicate createUserFilter(AggregateReportQueryContext queryContext) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportEntryService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportEntryService.java index d23eaa28184..2a88575099b 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportEntryService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportEntryService.java @@ -61,6 +61,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return createUserFilter(cb, cq, from); + } + @Override protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java index 4df1f400061..30b458a5769 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java @@ -154,6 +154,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return createUserFilter(cb, cq, from); + } + /** * Filters users analogous to reportingUsers in ::createUserFilter * diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java index 6178b80b965..a05f4121968 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java @@ -209,6 +209,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return createUserFilter(cb, cq, from); + } + /** * @param additionalTestUuids * {@link AdditionalTest}s identified by {@code uuid} to be deleted. diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java index 9d6c938179d..dfb567bceaa 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java @@ -327,6 +327,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return createUserFilter(cb, cq, from); + } + @Override public void delete(PathogenTest pathogenTest, DeletionDetails deletionDetails) { super.delete(pathogenTest, deletionDetails); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java index 2c707b25c04..e77a779d163 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java @@ -583,8 +583,17 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return createUserFilter(new SampleQueryContext(cb, cq, from), null, true); + } + public Predicate createUserFilter(SampleQueryContext sampleQueryContext, SampleCriteria criteria) { + return createUserFilter(sampleQueryContext, criteria, false); + } + + @SuppressWarnings("rawtypes") + public Predicate createUserFilter(SampleQueryContext sampleQueryContext, SampleCriteria criteria, boolean obsolete) { final CriteriaQuery cq = sampleQueryContext.getQuery(); final CriteriaBuilder cb = sampleQueryContext.getCriteriaBuilder(); @@ -605,7 +614,11 @@ public Predicate createUserFilter(SampleQueryContext sampleQueryContext, SampleC if (criteria != null && criteria.getSampleAssociationType() != null && criteria.getSampleAssociationType() != SampleAssociationType.ALL) { final SampleAssociationType sampleAssociationType = criteria.getSampleAssociationType(); if (sampleAssociationType == SampleAssociationType.CASE) { - filter = CriteriaBuilderHelper.or(cb, filter, caseService.createUserFilter(new CaseQueryContext(cb, cq, joins.getCaseJoins()), null)); + if (obsolete) { + filter = CriteriaBuilderHelper.or(cb, filter, caseService.createUserFilterForObsoleteSync(new CaseQueryContext(cb, cq, joins.getCaseJoins()), null)); + } else { + filter = CriteriaBuilderHelper.or(cb, filter, caseService.createUserFilter(new CaseQueryContext(cb, cq, joins.getCaseJoins()), null)); + } } else if (sampleAssociationType == SampleAssociationType.CONTACT && !RequestContextHolder.isMobileSync()) { filter = CriteriaBuilderHelper .or(cb, filter, contactService.createUserFilter(new ContactQueryContext(cb, cq, joins.getContactJoins()), null)); @@ -615,30 +628,53 @@ public Predicate createUserFilter(SampleQueryContext sampleQueryContext, SampleC filter, eventParticipantService.createUserFilter(new EventParticipantQueryContext(cb, cq, joins.getEventParticipantJoins()))); } - } else if (currentUser.getLimitedDisease() != null) { - filter = CriteriaBuilderHelper.and( - cb, - filter, - CriteriaBuilderHelper.or( + } else { + Predicate caseUserFilter; + if (obsolete) { + caseUserFilter = caseService.createUserFilterForObsoleteSync(new CaseQueryContext(cb, cq, joins.getCaseJoins()), null); + } else { + caseUserFilter = caseService.createUserFilter(new CaseQueryContext(cb, cq, joins.getCaseJoins()), null); + } + if (currentUser.getLimitedDisease() != null) { + filter = CriteriaBuilderHelper.and( cb, - caseService.createUserFilter(new CaseQueryContext(cb, cq, joins.getCaseJoins()), null), + filter, + CriteriaBuilderHelper.or( + cb, + caseUserFilter, + RequestContextHolder.isMobileSync() + ? null + : contactService.createUserFilter(new ContactQueryContext(cb, cq, joins.getContactJoins()), null), + RequestContextHolder.isMobileSync() + ? null + : eventParticipantService.createUserFilter(new EventParticipantQueryContext(cb, cq, joins.getEventParticipantJoins())))); + } else { + filter = CriteriaBuilderHelper.or( + cb, + filter, + caseUserFilter, RequestContextHolder.isMobileSync() ? null : contactService.createUserFilter(new ContactQueryContext(cb, cq, joins.getContactJoins()), null), RequestContextHolder.isMobileSync() ? null - : eventParticipantService.createUserFilter(new EventParticipantQueryContext(cb, cq, joins.getEventParticipantJoins())))); - } else { - filter = CriteriaBuilderHelper.or( - cb, - filter, - caseService.createUserFilter(new CaseQueryContext(cb, cq, joins.getCaseJoins()), null), - RequestContextHolder.isMobileSync() - ? null - : contactService.createUserFilter(new ContactQueryContext(cb, cq, joins.getContactJoins()), null), - RequestContextHolder.isMobileSync() - ? null - : eventParticipantService.createUserFilter(new EventParticipantQueryContext(cb, cq, joins.getEventParticipantJoins()))); + : eventParticipantService.createUserFilter(new EventParticipantQueryContext(cb, cq, joins.getEventParticipantJoins()))); + } + } + + if (RequestContextHolder.isMobileSync()) { + if (obsolete) { + Predicate limitedChangeDateForObsoletePredicate = + CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilterForObsoleteEntities(cb, sampleQueryContext.getRoot())); + if (limitedChangeDateForObsoletePredicate != null) { + filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDateForObsoletePredicate); + } + } else { + Predicate limitedChangeDatePredicate = CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilter(cb, sampleQueryContext.getRoot())); + if (limitedChangeDatePredicate != null) { + filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDatePredicate); + } + } } return filter; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/share/ExternalShareInfoService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/share/ExternalShareInfoService.java index ab83983e2f2..83c4a17b203 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/share/ExternalShareInfoService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/share/ExternalShareInfoService.java @@ -66,6 +66,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + @Override protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/origin/SormasToSormasOriginInfoService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/origin/SormasToSormasOriginInfoService.java index d1545f095cc..7d06b18880d 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/origin/SormasToSormasOriginInfoService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/origin/SormasToSormasOriginInfoService.java @@ -45,6 +45,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + @Override protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/incoming/SormasToSormasShareRequestService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/incoming/SormasToSormasShareRequestService.java index cbb6d4448c2..e057277721a 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/incoming/SormasToSormasShareRequestService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/incoming/SormasToSormasShareRequestService.java @@ -58,6 +58,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + @Override protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/ShareRequestInfoService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/ShareRequestInfoService.java index 8f8f13ae8a3..252555a2a82 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/ShareRequestInfoService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/ShareRequestInfoService.java @@ -47,6 +47,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + @Override protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfoService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfoService.java index 52d23f28860..8ea02a6ab05 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfoService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfoService.java @@ -71,6 +71,12 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + // no filter by user needed + return null; + } + @Override protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java index 096b65f2484..855457ef945 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java @@ -158,6 +158,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return createUserFilter(new TaskQueryContext(cb, cq, from), null, true); + } + public Predicate createUserFilter(TaskQueryContext taskQueryContext) { return createUserFilter(taskQueryContext, null); } @@ -189,6 +194,14 @@ private boolean hasContextOrNoContext(TaskCriteria taskCriteria, TaskContext tas } public Predicate createUserFilter(TaskQueryContext taskQueryContext, TaskCriteria taskCriteria) { + return createUserFilter(taskQueryContext, taskCriteria, false); + } + + public Predicate createUserFilterForObsolete(TaskQueryContext taskQueryContext, TaskCriteria taskCriteria) { + return createUserFilter(taskQueryContext, taskCriteria, true); + } + + public Predicate createUserFilter(TaskQueryContext taskQueryContext, TaskCriteria taskCriteria, boolean obsolete) { User currentUser = getCurrentUser(); if (currentUser == null) { @@ -218,40 +231,90 @@ public Predicate createUserFilter(TaskQueryContext taskQueryContext, TaskCriteri Predicate filter = cb.equal(taskPath.get(Task.CREATOR_USER), currentUser); filter = cb.or(filter, cb.equal(taskPath.get(Task.ASSIGNEE_USER), currentUser)); - Predicate caseFilter = hasContextOrNoContext(taskCriteria, TaskContext.CASE) - ? caseService.createUserFilter( - new CaseQueryContext(cb, cq, joins.getCaseJoins()), - taskCriteria != null - ? new CaseUserFilterCriteria().excludeLimitedSyncRestrictions(taskCriteria.isExcludeLimitedSyncRestrictions()) - : null) - : null; - if (caseFilter != null) { - filter = cb.or(filter, caseFilter); - } - Predicate contactFilter = hasContextOrNoContext(taskCriteria, TaskContext.CONTACT) - ? contactService.createUserFilter(new ContactQueryContext(cb, cq, joins.getContactJoins())) - : null; - if (contactFilter != null) { - filter = cb.or( - filter, - CriteriaBuilderHelper - .or(cb, contactFilter, createAssigneeOrObserverFilter(cb, joins.getAssignee(), joins.getTaskObservers(), currentUser))); - } - Predicate eventFilter = hasContextOrNoContext(taskCriteria, TaskContext.EVENT) - ? eventService.createUserFilter(new EventQueryContext(cb, cq, joins.getEventJoins())) - : null; - if (eventFilter != null) { - filter = cb.or(filter, eventFilter); + if (obsolete) + { + Predicate caseFilter = hasContextOrNoContext(taskCriteria, TaskContext.CASE) + ? caseService.createUserFilterForObsoleteSync( + new CaseQueryContext(cb, cq, joins.getCaseJoins()), + taskCriteria != null + ? new CaseUserFilterCriteria().excludeLimitedSyncRestrictions(taskCriteria.isExcludeLimitedSyncRestrictions()) + : null) + : null; + if (caseFilter != null) { + filter = cb.or(filter, caseFilter); + } + Predicate contactFilter = hasContextOrNoContext(taskCriteria, TaskContext.CONTACT) + ? contactService.createUserFilterForObsoleteSync(new ContactQueryContext(cb, cq, joins.getContactJoins())) + : null; + if (contactFilter != null) { + filter = cb.or( + filter, + CriteriaBuilderHelper + .or(cb, contactFilter, createAssigneeOrObserverFilter(cb, joins.getAssignee(), joins.getTaskObservers(), currentUser))); + } + Predicate eventFilter = hasContextOrNoContext(taskCriteria, TaskContext.EVENT) + ? eventService.createUserFilterForObsoleteSync(new EventQueryContext(cb, cq, joins.getEventJoins())) + : null; + if (eventFilter != null) { + filter = cb.or(filter, eventFilter); + } + } else { + Predicate caseFilter = hasContextOrNoContext(taskCriteria, TaskContext.CASE) + ? caseService.createUserFilter( + new CaseQueryContext(cb, cq, joins.getCaseJoins()), + taskCriteria != null + ? new CaseUserFilterCriteria().excludeLimitedSyncRestrictions(taskCriteria.isExcludeLimitedSyncRestrictions()) + : null) + : null; + if (caseFilter != null) { + filter = cb.or(filter, caseFilter); + } + Predicate contactFilter = hasContextOrNoContext(taskCriteria, TaskContext.CONTACT) + ? contactService.createUserFilter(new ContactQueryContext(cb, cq, joins.getContactJoins())) + : null; + if (contactFilter != null) { + filter = cb.or( + filter, + CriteriaBuilderHelper + .or(cb, contactFilter, createAssigneeOrObserverFilter(cb, joins.getAssignee(), joins.getTaskObservers(), currentUser))); + } + Predicate eventFilter = hasContextOrNoContext(taskCriteria, TaskContext.EVENT) + ? eventService.createUserFilter(new EventQueryContext(cb, cq, joins.getEventJoins())) + : null; + if (eventFilter != null) { + filter = cb.or(filter, eventFilter); + } + Predicate travelEntryFilter = hasContextOrNoContext(taskCriteria, TaskContext.TRAVEL_ENTRY) + ? travelEntryService.createUserFilter(new TravelEntryQueryContext(cb, cq, joins.getTravelEntryJoins())) + : null; + if (travelEntryFilter != null) { + filter = cb.or(filter, travelEntryFilter); + } } Predicate travelEntryFilter = hasContextOrNoContext(taskCriteria, TaskContext.TRAVEL_ENTRY) - ? travelEntryService.createUserFilter(new TravelEntryQueryContext(cb, cq, joins.getTravelEntryJoins())) - : null; + ? travelEntryService.createUserFilter(new TravelEntryQueryContext(cb, cq, joins.getTravelEntryJoins())) + : null; if (travelEntryFilter != null) { filter = cb.or(filter, travelEntryFilter); } filter = cb.or(filter, assigneeFilter); + if (RequestContextHolder.isMobileSync()) { + if (obsolete) { + Predicate limitedChangeDateForObsoletePredicate = + CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilterForObsoleteEntities(cb, taskQueryContext.getRoot())); + if (limitedChangeDateForObsoletePredicate != null) { + filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDateForObsoletePredicate); + } + } else { + Predicate limitedChangeDatePredicate = CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilter(cb, taskQueryContext.getRoot())); + if (limitedChangeDatePredicate != null) { + filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDatePredicate); + } + } + } + if ((taskCriteria == null || !taskCriteria.isExcludeLimitedSyncRestrictions()) && featureConfigurationFacade .isPropertyValueTrue(FeatureType.LIMITED_SYNCHRONIZATION, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES) @@ -290,7 +353,7 @@ protected List getAdditionalObsoleteUuidsPredicates(Date since, Crite @Override protected Predicate getUserFilterForObsoleteUuids(CriteriaBuilder cb, CriteriaQuery cq, Root from) { - return createUserFilter(new TaskQueryContext(cb, cq, from), new TaskCriteria().excludeLimitedSyncRestrictions(true)); + return createUserFilterForObsolete(new TaskQueryContext(cb, cq, from), new TaskCriteria().excludeLimitedSyncRestrictions(true)); } public Predicate createAssigneeFilter(CriteriaBuilder cb, Join assigneeUserJoin) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java index 8929351ef0d..51378a07855 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java @@ -147,6 +147,13 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + + Join therapy = from.join(Prescription.THERAPY, JoinType.LEFT); + return caseService.createUserFilterForObsoleteSync(new CaseQueryContext(cb, cq, new CaseJoins(therapy.join(Therapy.CASE, JoinType.LEFT)))); + } + @Override public boolean inJurisdictionOrOwned(Prescription entity) { return fulfillsCondition(entity, (cb, cq, from) -> inJurisdictionOrOwned(cb, cq, from)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java index 80c615ec469..776383bddea 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java @@ -144,6 +144,12 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + Join therapy = from.join(Treatment.THERAPY, JoinType.LEFT); + return caseService.createUserFilterForObsoleteSync(new CaseQueryContext(cb, cq, new CaseJoins(therapy.join(Therapy.CASE, JoinType.LEFT)))); + } + public void unlinkPrescriptionFromTreatments(List treatmentUuids){ CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaUpdate criteriaUpdate = cb.createCriteriaUpdate(getElementClass()); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/BaseTravelEntryService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/BaseTravelEntryService.java index 15de0bd4402..52b5b814b17 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/BaseTravelEntryService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/BaseTravelEntryService.java @@ -58,6 +58,11 @@ protected Predicate createUserFilterInternal(CriteriaBuilder cb, CriteriaQuery c return createUserFilter(new TravelEntryQueryContext(cb, cq, from)); } + @Override + public Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return createUserFilter(new TravelEntryQueryContext(cb, cq, from)); + } + public Predicate createUserFilter(TravelEntryQueryContext qc) { User currentUser = getCurrentUser(); if (currentUser == null) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserRoleService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserRoleService.java index 2291e582acc..c78723c0f79 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserRoleService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserRoleService.java @@ -66,6 +66,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + @Override protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { return null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserService.java index 5149ea2094f..ac99b403eb2 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserService.java @@ -718,6 +718,12 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + // no filter by user needed + return null; + } + public Predicate createCurrentUserJurisdictionFilter(CriteriaBuilder cb, From from) { if (hasRight(UserRight.SEE_PERSONAL_DATA_OUTSIDE_JURISDICTION)) { return cb.conjunction(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/vaccination/VaccinationService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/vaccination/VaccinationService.java index 950ee102f79..d374d4c6b57 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/vaccination/VaccinationService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/vaccination/VaccinationService.java @@ -369,6 +369,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + @Override public boolean inJurisdictionOrOwned(Vaccination entity) { return fulfillsCondition(entity, this::inJurisdictionOrOwned); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java index 47329c5ff59..171e4adfb23 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java @@ -200,6 +200,11 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } + @SuppressWarnings("rawtypes") protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbUserFilterTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbUserFilterTest.java index 84c1410197c..8a5254d085c 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbUserFilterTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbUserFilterTest.java @@ -154,7 +154,7 @@ public void testGetCasesWithExcludeNoCaseClassifiedAndMaxChangedDate() { FeatureConfiguration singleResult = (FeatureConfiguration) query.getSingleResult(); HashMap properties = new HashMap<>(); properties.put(FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES, true); - properties.put(FeatureTypeProperty.MAX_CHANGE_DATE_SYNCHRONIZATION, 30); + properties.put(FeatureTypeProperty.MAX_CHANGE_DATE_PERIOD, 30); singleResult.setProperties(properties); em.save(singleResult); From 7bee00969576d50081a7bb121857e2f2c7c415e4 Mon Sep 17 00:00:00 2001 From: Levente Gal Date: Fri, 16 Dec 2022 14:42:04 +0200 Subject: [PATCH 015/166] #11161 [S2S] Share box 'Share with' text field is duplicated after revoking a share request - cleanup displaying share info on the UI --- .../ui/immunization/ImmunizationDataView.java | 2 +- .../sormas/ui/samples/SampleDataView.java | 2 +- .../SormasToSormasListComponent.java | 93 +++++++++---------- 3 files changed, 46 insertions(+), 51 deletions(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/ImmunizationDataView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/ImmunizationDataView.java index 57b48790bdb..8194d6c97ba 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/ImmunizationDataView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/ImmunizationDataView.java @@ -64,7 +64,7 @@ protected void initView(String params) { sormasToSormasListComponent.addStyleNames(CssStyles.SIDE_COMPONENT); sormasToSormasLocLayout.addComponent(sormasToSormasListComponent); - layout.addComponent(sormasToSormasLocLayout, SORMAS_TO_SORMAS_LOC); + layout.addSidePanelComponent(sormasToSormasLocLayout, SORMAS_TO_SORMAS_LOC); } final String uuid = immunization.getUuid(); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleDataView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleDataView.java index 5738331fb1c..060043ed949 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleDataView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleDataView.java @@ -149,7 +149,7 @@ protected void initView(String params) { sormasToSormasListComponent.addStyleNames(CssStyles.SIDE_COMPONENT); sormasToSormasLocLayout.addComponent(sormasToSormasListComponent); - layout.addComponent(sormasToSormasLocLayout, SORMAS_TO_SORMAS_LOC); + layout.addSidePanelComponent(sormasToSormasLocLayout, SORMAS_TO_SORMAS_LOC); } final String uuid = sampleDto.getUuid(); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/SormasToSormasListComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/SormasToSormasListComponent.java index 4ec9d147c90..8b52d19e685 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/SormasToSormasListComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/SormasToSormasListComponent.java @@ -68,7 +68,9 @@ public class SormasToSormasListComponent extends VerticalLayout { private static final long serialVersionUID = -7189942121987530912L; protected final Logger logger = LoggerFactory.getLogger(getClass()); + private final String notSharedCaptionTag; private final SormasToSormasList sormasToSormasList; + private VerticalLayout contentLayout; private SormasToSormasOriginInfoDto originInfo; private ShareDataLoader loadShares; @@ -76,8 +78,8 @@ public class SormasToSormasListComponent extends VerticalLayout { public SormasToSormasListComponent(CaseDataDto caze, boolean isEditAllowed) { this.isEditAllowed = isEditAllowed; - sormasToSormasList = - new SormasToSormasList(caze.getSormasToSormasOriginInfo() == null, Captions.sormasToSormasCaseNotShared, this::reloadListSync); + sormasToSormasList = new SormasToSormasList(this::reloadListSync); + notSharedCaptionTag = Captions.sormasToSormasCaseNotShared; initLayout( caze.getSormasToSormasOriginInfo(), @@ -86,9 +88,9 @@ public SormasToSormasListComponent(CaseDataDto caze, boolean isEditAllowed) { } public SormasToSormasListComponent(ContactDto contact, boolean isEditAllowed) { - sormasToSormasList = - new SormasToSormasList(contact.getSormasToSormasOriginInfo() == null, Captions.sormasToSormasContactNotShared, this::reloadListSync); this.isEditAllowed = isEditAllowed; + sormasToSormasList = new SormasToSormasList(this::reloadListSync); + notSharedCaptionTag = Captions.sormasToSormasContactNotShared; initLayout( contact.getSormasToSormasOriginInfo(), @@ -97,7 +99,8 @@ public SormasToSormasListComponent(ContactDto contact, boolean isEditAllowed) { } public SormasToSormasListComponent(SampleDto sample) { - sormasToSormasList = new SormasToSormasList(sample.getSormasToSormasOriginInfo() == null, Captions.sormasToSormasSampleNotShared, null); + sormasToSormasList = new SormasToSormasList(null); + notSharedCaptionTag = Captions.sormasToSormasSampleNotShared; initLayout( sample.getSormasToSormasOriginInfo(), @@ -111,8 +114,8 @@ public SormasToSormasListComponent(SampleDto sample) { public SormasToSormasListComponent(EventDto event) { - sormasToSormasList = - new SormasToSormasList(event.getSormasToSormasOriginInfo() == null, Captions.sormasToSormasEventNotShared, this::reloadListSync); + sormasToSormasList = new SormasToSormasList(this::reloadListSync); + notSharedCaptionTag = Captions.sormasToSormasEventNotShared; initLayout( event.getSormasToSormasOriginInfo(), @@ -121,8 +124,8 @@ public SormasToSormasListComponent(EventDto event) { } public SormasToSormasListComponent(EventParticipantDto eventParticipant) { - sormasToSormasList = - new SormasToSormasList(eventParticipant.getSormasToSormasOriginInfo() == null, Captions.sormasToSormasEventParticipantNotShared, null); + sormasToSormasList = new SormasToSormasList(null); + notSharedCaptionTag = Captions.sormasToSormasEventParticipantNotShared; initLayout( eventParticipant.getSormasToSormasOriginInfo(), @@ -131,8 +134,8 @@ public SormasToSormasListComponent(EventParticipantDto eventParticipant) { } public SormasToSormasListComponent(ImmunizationDto immunzation) { - sormasToSormasList = - new SormasToSormasList(immunzation.getSormasToSormasOriginInfo() == null, Captions.sormasToSormasImmunizationNotShared, null); + sormasToSormasList = new SormasToSormasList(null); + notSharedCaptionTag = Captions.sormasToSormasImmunizationNotShared; initLayout( immunzation.getSormasToSormasOriginInfo(), @@ -158,9 +161,6 @@ private void initLayout(SormasToSormasOriginInfoDto originInfo, ShareDataLoader componentHeader.setWidth(100, Unit.PERCENTAGE); addComponent(componentHeader); - addComponent(sormasToSormasList); - reloadList(); - Label header = new Label(I18nProperties.getCaption(Captions.sormasToSormasListTitle)); header.addStyleName(CssStyles.H3); componentHeader.addComponent(header); @@ -172,12 +172,22 @@ private void initLayout(SormasToSormasOriginInfoDto originInfo, ShareDataLoader componentHeader.addComponent(shareButtonButton); componentHeader.setComponentAlignment(shareButtonButton, Alignment.MIDDLE_RIGHT); } + + contentLayout = new VerticalLayout(); + contentLayout.setMargin(false); + contentLayout.setSpacing(false); + addComponent(contentLayout); + + reloadList(); } public void reloadList() { UI currentUI = UI.getCurrent(); - sormasToSormasList.showPlaceholder(I18nProperties.getString(Strings.sormasToSormasLoadingShares)); + contentLayout.removeAllComponents(); + + Label placeHolder = new Label(I18nProperties.getString(Strings.sormasToSormasLoadingShares)); + contentLayout.addComponent(placeHolder); Thread loadSharesThread = new Thread(() -> { try { @@ -193,7 +203,7 @@ public void reloadList() { currentUI.setPollInterval(-1); currentUI.access(() -> { - sormasToSormasList.showPlaceholder(I18nProperties.getString(Strings.errorSormasToSormasLoadShares)); + placeHolder.setValue(I18nProperties.getString(Strings.errorSormasToSormasLoadShares)); }); } }); @@ -226,11 +236,13 @@ private void reloadListWithWrapper(Consumer wrapUiChanges) { wrapUiChanges.accept(() -> { try { + contentLayout.removeAllComponents(); + // render origin if (originInfo != null) { HorizontalLayout originLayout = buildSormasOriginInfo(originInfo, isOwnedByOrigin); originLayout.addStyleName(CssStyles.VSPACE_3); - addComponent(originLayout, getComponentIndex(sormasToSormasList)); + contentLayout.addComponent(originLayout); } // render the owner of the entity @@ -244,7 +256,7 @@ private void reloadListWithWrapper(Consumer wrapUiChanges) { if (ownerLayout != null) { ownerLayout.addStyleName(CssStyles.VSPACE_3); - addComponent(ownerLayout, getComponentIndex(sormasToSormasList)); + contentLayout.addComponent(ownerLayout); } } @@ -303,24 +315,23 @@ private void reloadListWithWrapper(Consumer wrapUiChanges) { listData.add(entryData); } - if (shareInfoList.size() > 0) { - if (listData.size() > 0) { - Label shareListLabel = new Label(I18nProperties.getCaption(Captions.sormasToSormasSharedWith)); - shareListLabel.addStyleNames(CssStyles.LABEL_BOLD, CssStyles.VSPACE_4); - addComponent(shareListLabel, getComponentIndex(sormasToSormasList)); + if (shareInfoList.size() > 0 && listData.size() > 0) { + Label shareListLabel = new Label(I18nProperties.getCaption(Captions.sormasToSormasSharedWith)); + shareListLabel.addStyleNames(CssStyles.LABEL_BOLD, CssStyles.VSPACE_4); + contentLayout.addComponent(shareListLabel); - sormasToSormasList.setData(listData); - } else { - sormasToSormasList.setVisible(false); - } - } else { - sormasToSormasList.showPlaceholder(null); + contentLayout.addComponent(sormasToSormasList); + sormasToSormasList.setData(listData); + } else if (contentLayout.getComponentCount() == 0) { + contentLayout.addComponent(new Label(I18nProperties.getCaption(notSharedCaptionTag))); } } catch (Exception e) { logger.error("Failed to load shares", e); - sormasToSormasList.showPlaceholder(I18nProperties.getString(Strings.errorSormasToSormasLoadShares)); + contentLayout.removeAllComponents(); + contentLayout.addComponent(new Label(I18nProperties.getString(Strings.errorSormasToSormasLoadShares))); } }); + } private String getOwnerOrganizationId(SormasToSormasShareInfoDto ownerShare, SormasToSormasOriginInfoDto rootOrigin, String ownOrganizationId) { @@ -479,16 +490,11 @@ private interface ShareDataLoader { private static class SormasToSormasList extends PaginationList { private static final long serialVersionUID = -4659924105492791566L; - private String defaultPlaceHolderText; - private final Label placeholderLabel; private final Runnable revokeCallback; - public SormasToSormasList(boolean showPlaceholder, String placeholderCaptionTag, Runnable revokeCallback) { + public SormasToSormasList(Runnable revokeCallback) { super(5); - this.defaultPlaceHolderText = placeholderCaptionTag != null ? I18nProperties.getCaption(placeholderCaptionTag) : null; - this.placeholderLabel = new Label(defaultPlaceHolderText); - this.placeholderLabel.setVisible(showPlaceholder); this.revokeCallback = revokeCallback; } @@ -497,22 +503,10 @@ public void reload() { } public void setData(List data) { - setEntries(data); - - listLayout.removeComponent(placeholderLabel); showPage(1); } - public void showPlaceholder(String placeholderText) { - setEntries(Collections.emptyList()); - showPage(1); - - placeholderLabel.setValue(placeholderText == null ? defaultPlaceHolderText : placeholderText); - listLayout.addComponent(placeholderLabel); - placeholderLabel.setVisible(true); - } - @Override protected void drawDisplayedEntries() { List displayedEntries = getDisplayedEntries(); @@ -575,7 +569,8 @@ public SormasToSormasShareListEntry(SormasToSormasShareListEntryData data, Runna addComponent(infoLayout); setExpandRatio(infoLayout, 1); - if (FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.SORMAS_TO_SORMAS_ACCEPT_REJECT) + if (revokeCallback != null + && FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.SORMAS_TO_SORMAS_ACCEPT_REJECT) && UserProvider.getCurrent().hasUserRight(UserRight.SORMAS_TO_SORMAS_SHARE) && data.shareUuid != null && data.status == ShareRequestStatus.PENDING From 16d1a9a14c8356c54dc318a455a546373a16e53c Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Mon, 19 Dec 2022 18:20:19 +0200 Subject: [PATCH 016/166] #8465 - Display soft-deleted entities to users that have the right to delete - changes after review --- .../de/symeda/sormas/api/i18n/Captions.java | 16 +++++++++------- .../src/main/resources/captions.properties | 2 ++ .../backend/campaign/CampaignService.java | 17 +++++++++++++---- .../ui/campaign/campaigns/CampaignsView.java | 9 +++++++-- .../sormas/ui/utils/components/CheckboxSet.java | 2 +- 5 files changed, 32 insertions(+), 14 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java index 79f276e63d4..fa4d3352e25 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java @@ -251,6 +251,7 @@ public interface Captions { String campaignActiveCampaigns = "campaignActiveCampaigns"; String campaignAdditionalChart = "campaignAdditionalChart"; String campaignAdditionalForm = "campaignAdditionalForm"; + String campaignAllActiveAndArchivedCampaigns = "campaignAllActiveAndArchivedCampaigns"; String campaignAllCampaigns = "campaignAllCampaigns"; String campaignArchivedCampaigns = "campaignArchivedCampaigns"; String campaignCampaignData = "campaignCampaignData"; @@ -262,6 +263,7 @@ public interface Captions { String campaignDashboardOrder = "campaignDashboardOrder"; String campaignDashboardSubTabName = "campaignDashboardSubTabName"; String campaignDashboardTabName = "campaignDashboardTabName"; + String campaignDeletedCampaigns = "campaignDeletedCampaigns"; String campaignDiagramGroupBy = "campaignDiagramGroupBy"; String CampaignFormData_area = "CampaignFormData.area"; String CampaignFormData_campaign = "CampaignFormData.campaign"; @@ -277,7 +279,6 @@ public interface Captions { String captionDefault = "captionDefault"; String caseActiveCases = "caseActiveCases"; String caseAllActiveAndArchivedCases = "caseAllActiveAndArchivedCases"; - String caseDeletedCases = "caseDeletedCases"; String caseArchivedCases = "caseArchivedCases"; String caseBackToDirectory = "caseBackToDirectory"; String caseCalculateCompleteness = "caseCalculateCompleteness"; @@ -448,6 +449,7 @@ public interface Captions { String CaseData_wasInQuarantineBeforeIsolation = "CaseData.wasInQuarantineBeforeIsolation"; String caseDataEnterHomeAddressNow = "caseDataEnterHomeAddressNow"; String caseDefaultView = "caseDefaultView"; + String caseDeletedCases = "caseDeletedCases"; String caseDetailedView = "caseDetailedView"; String caseDocuments = "caseDocuments"; String caseEditData = "caseEditData"; @@ -729,8 +731,8 @@ public interface Captions { String contactContactsOverview = "contactContactsOverview"; String contactCreateContactCase = "contactCreateContactCase"; String contactCreateNew = "contactCreateNew"; - String contactDetailedOverview = "contactDetailedOverview"; String contactDeletedContacts = "contactDeletedContacts"; + String contactDetailedOverview = "contactDetailedOverview"; String ContactExport_address = "ContactExport.address"; String ContactExport_addressCommunity = "ContactExport.addressCommunity"; String ContactExport_addressDistrict = "ContactExport.addressDistrict"; @@ -1148,8 +1150,8 @@ public interface Captions { String eventAllGroups = "eventAllGroups"; String eventArchivedEvents = "eventArchivedEvents"; String eventArchivedGroups = "eventArchivedGroups"; - String eventDeletedEvents = "eventDeletedEvents"; String eventDefaultView = "eventDefaultView"; + String eventDeletedEvents = "eventDeletedEvents"; String eventEditEvent = "eventEditEvent"; String eventEditEventGroup = "eventEditEventGroup"; String eventEventActions = "eventEventActions"; @@ -1199,9 +1201,9 @@ public interface Captions { String EventParticipant_sex = "EventParticipant.sex"; String EventParticipant_uuid = "EventParticipant.uuid"; String EventParticipant_vaccinationStatus = "EventParticipant.vaccinationStatus"; + String eventParticipantActiveAndArchivedEventParticipants = "eventParticipantActiveAndArchivedEventParticipants"; String eventParticipantActiveEventParticipants = "eventParticipantActiveEventParticipants"; String eventParticipantAddPerson = "eventParticipantAddPerson"; - String eventParticipantActiveAndArchivedEventParticipants = "eventParticipantActiveAndArchivedEventParticipants"; String eventParticipantArchivedEventParticipants = "eventParticipantArchivedEventParticipants"; String eventParticipantContactCountOnlyWithSourceCaseInEvent = "eventParticipantContactCountOnlyWithSourceCaseInEvent"; String eventParticipantCreateNew = "eventParticipantCreateNew"; @@ -1476,10 +1478,10 @@ public interface Captions { String Immunization_validFrom = "Immunization.validFrom"; String Immunization_validUntil = "Immunization.validUntil"; String immunizationActiveImmunizations = "immunizationActiveImmunizations"; - String immunizationArchivedImmunizations = "immunizationArchivedImmunizations"; String immunizationAllActiveAndArchivedImmunizations = "immunizationAllActiveAndArchivedImmunizations"; - String immunizationDeletedImmunizations = "immunizationDeletedImmunizations"; + String immunizationArchivedImmunizations = "immunizationArchivedImmunizations"; String immunizationCreateNewImmunization = "immunizationCreateNewImmunization"; + String immunizationDeletedImmunizations = "immunizationDeletedImmunizations"; String immunizationImmunizationsList = "immunizationImmunizationsList"; String immunizationKeepImmunization = "immunizationKeepImmunization"; String immunizationNewImmunization = "immunizationNewImmunization"; @@ -2361,8 +2363,8 @@ public interface Captions { String TravelEntry_changeDate = "TravelEntry.changeDate"; String TravelEntry_creationDate = "TravelEntry.creationDate"; String TravelEntry_dateOfArrival = "TravelEntry.dateOfArrival"; - String TravelEntry_deletionReason = "TravelEntry.deletionReason"; String TravelEntry_deletedTravelEntries = "TravelEntry.deletedTravelEntries"; + String TravelEntry_deletionReason = "TravelEntry.deletionReason"; String TravelEntry_differentPointOfEntryJurisdiction = "TravelEntry.differentPointOfEntryJurisdiction"; String TravelEntry_diseaseVariant = "TravelEntry.diseaseVariant"; String TravelEntry_externalId = "TravelEntry.externalId"; diff --git a/sormas-api/src/main/resources/captions.properties b/sormas-api/src/main/resources/captions.properties index 8b3191830f9..cfb2d4e87c2 100644 --- a/sormas-api/src/main/resources/captions.properties +++ b/sormas-api/src/main/resources/captions.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java index 15d77cd4416..6dd0fad5408 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java @@ -13,9 +13,11 @@ import de.symeda.sormas.api.EntityRelevanceStatus; import de.symeda.sormas.api.campaign.CampaignCriteria; import de.symeda.sormas.api.utils.DataHelper; +import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.common.AbstractCoreAdoService; import de.symeda.sormas.backend.common.AbstractDomainObject; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; +import de.symeda.sormas.backend.contact.Contact; @Stateless @LocalBean @@ -42,9 +44,9 @@ public Predicate buildCriteriaFilter(CampaignQueryContext queryContext, Campaign From from = queryContext.getRoot(); Predicate filter = null; - if (campaignCriteria.getDeleted() != null) { - filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(Campaign.DELETED), campaignCriteria.getDeleted())); - } +// if (campaignCriteria.getDeleted() != null) { +// filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(Campaign.DELETED), campaignCriteria.getDeleted())); +// } if (campaignCriteria.getStartDateAfter() != null || campaignCriteria.getStartDateBefore() != null) { filter = CriteriaBuilderHelper.and( cb, @@ -74,8 +76,15 @@ public Predicate buildCriteriaFilter(CampaignQueryContext queryContext, Campaign .and(cb, filter, cb.or(cb.equal(from.get(Campaign.ARCHIVED), false), cb.isNull(from.get(Campaign.ARCHIVED)))); } else if (campaignCriteria.getRelevanceStatus() == EntityRelevanceStatus.ARCHIVED) { filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(Campaign.ARCHIVED), true)); + } else if (campaignCriteria.getRelevanceStatus() == EntityRelevanceStatus.DELETED) { + filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(Case.DELETED), true)); } } + + if (campaignCriteria.getRelevanceStatus() != EntityRelevanceStatus.DELETED) { + filter = CriteriaBuilderHelper.and(cb, filter, cb.isFalse(from.get(Contact.DELETED))); + } + return filter; } @@ -113,7 +122,7 @@ public Predicate createActiveCampaignsFilter(CriteriaBuilder cb, Root } @Override - public Predicate inJurisdictionOrOwned(CriteriaBuilder cb, CriteriaQuery query, From from) { + public Predicate inJurisdictionOrOwned(CriteriaBuilder cb, CriteriaQuery query, From from) { // Currently no jurisdiction checks for campaigns return cb.conjunction(); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigns/CampaignsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigns/CampaignsView.java index a8d26b66b29..f64c482acf1 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigns/CampaignsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigns/CampaignsView.java @@ -123,8 +123,13 @@ private HorizontalLayout createFilterBar() { relevanceStatusFilter.addItems((Object[]) EntityRelevanceStatus.values()); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE, I18nProperties.getCaption(Captions.campaignActiveCampaigns)); relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ARCHIVED, I18nProperties.getCaption(Captions.campaignArchivedCampaigns)); - relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE_AND_ARCHIVED, I18nProperties.getCaption(Captions.campaignAllCampaigns)); - relevanceStatusFilter.removeItem(EntityRelevanceStatus.DELETED); + relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.ACTIVE_AND_ARCHIVED, I18nProperties.getCaption(Captions.campaignAllActiveAndArchivedCampaigns)); + if (UserProvider.getCurrent().hasUserRight(UserRight.CAMPAIGN_DELETE)) { + relevanceStatusFilter.setItemCaption(EntityRelevanceStatus.DELETED, I18nProperties.getCaption(Captions.campaignDeletedCampaigns)); + } else { + relevanceStatusFilter.removeItem(EntityRelevanceStatus.DELETED); + } + relevanceStatusFilter.addValueChangeListener(e -> { criteria.relevanceStatus((EntityRelevanceStatus) e.getProperty().getValue()); navigateTo(criteria); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/components/CheckboxSet.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/components/CheckboxSet.java index 1582fbc39e7..689b57b5101 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/components/CheckboxSet.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/components/CheckboxSet.java @@ -72,7 +72,7 @@ protected Component initContent() { } public void setItems(List items, Function groupingFunction, Function itemDescriptionProvider) { - this.items = items; + this.items = items; this.groupingFunction = groupingFunction; this.itemDescriptionProvider = itemDescriptionProvider; From a205bf521d3a3945c004727e26a9b07a6dac6c78 Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Tue, 20 Dec 2022 10:46:02 +0200 Subject: [PATCH 017/166] #8465 - Display soft-deleted entities to users that have the right to delete - changes after review --- .../symeda/sormas/api/campaign/CampaignCriteria.java | 11 ----------- .../action/EventActionIndexDtoReasultTransformer.java | 4 ++-- .../sormas/backend/campaign/CampaignService.java | 9 ++------- 3 files changed, 4 insertions(+), 20 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/campaign/CampaignCriteria.java b/sormas-api/src/main/java/de/symeda/sormas/api/campaign/CampaignCriteria.java index b8908fbc945..3b8fca39830 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/campaign/CampaignCriteria.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/campaign/CampaignCriteria.java @@ -15,7 +15,6 @@ public class CampaignCriteria extends BaseCriteria implements Serializable { private Date startDateBefore; private Date endDateAfter; private Date endDateBefore; - private Boolean deleted = Boolean.FALSE; private String freeText; private EntityRelevanceStatus relevanceStatus; @@ -55,16 +54,6 @@ public Date getEndDateBefore() { return endDateBefore; } - public CampaignCriteria deleted(Boolean deleted) { - this.deleted = deleted; - return this; - } - - @IgnoreForUrl - public Boolean getDeleted() { - return deleted; - } - public CampaignCriteria freeText(String freeText) { this.freeText = freeText; return this; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/action/EventActionIndexDtoReasultTransformer.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/action/EventActionIndexDtoReasultTransformer.java index 43447497782..a0234e93c1f 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/action/EventActionIndexDtoReasultTransformer.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/action/EventActionIndexDtoReasultTransformer.java @@ -52,8 +52,8 @@ public Object transformTuple(Object[] objects, String[] strings) { (ActionPriority) objects[25], actionLastModifiedBy, actionCreatorUser, - (DeletionReason) objects[33], - (String) objects[34]); + (DeletionReason) objects[41], + (String) objects[42]); } @Override diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java index 6dd0fad5408..691f535b1c0 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java @@ -13,11 +13,9 @@ import de.symeda.sormas.api.EntityRelevanceStatus; import de.symeda.sormas.api.campaign.CampaignCriteria; import de.symeda.sormas.api.utils.DataHelper; -import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.common.AbstractCoreAdoService; import de.symeda.sormas.backend.common.AbstractDomainObject; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; -import de.symeda.sormas.backend.contact.Contact; @Stateless @LocalBean @@ -44,9 +42,6 @@ public Predicate buildCriteriaFilter(CampaignQueryContext queryContext, Campaign From from = queryContext.getRoot(); Predicate filter = null; -// if (campaignCriteria.getDeleted() != null) { -// filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(Campaign.DELETED), campaignCriteria.getDeleted())); -// } if (campaignCriteria.getStartDateAfter() != null || campaignCriteria.getStartDateBefore() != null) { filter = CriteriaBuilderHelper.and( cb, @@ -77,12 +72,12 @@ public Predicate buildCriteriaFilter(CampaignQueryContext queryContext, Campaign } else if (campaignCriteria.getRelevanceStatus() == EntityRelevanceStatus.ARCHIVED) { filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(Campaign.ARCHIVED), true)); } else if (campaignCriteria.getRelevanceStatus() == EntityRelevanceStatus.DELETED) { - filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(Case.DELETED), true)); + filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(Campaign.DELETED), true)); } } if (campaignCriteria.getRelevanceStatus() != EntityRelevanceStatus.DELETED) { - filter = CriteriaBuilderHelper.and(cb, filter, cb.isFalse(from.get(Contact.DELETED))); + filter = CriteriaBuilderHelper.and(cb, filter, cb.isFalse(from.get(Campaign.DELETED))); } return filter; From 278d441eeb36a5a11faf450d704bcf3750489137 Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Wed, 21 Dec 2022 11:43:04 +0200 Subject: [PATCH 018/166] #11017 - Persons with incomplete home addresses from different jurisdictions can not be merged --- .../sormas/api/person/PersonFacade.java | 2 +- .../backend/person/PersonFacadeEjb.java | 17 +++++++++++++++- .../backend/person/PersonFacadeEjbTest.java | 20 +++++++++++++++++-- .../sormas/ui/person/PersonController.java | 6 +++++- 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/person/PersonFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/person/PersonFacade.java index c74b44060fe..9e53baf4651 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/person/PersonFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/person/PersonFacade.java @@ -82,7 +82,7 @@ public interface PersonFacade extends BaseFacade personInde 800, confirm -> { if (Boolean.TRUE.equals(confirm)) { - FacadeProvider.getPersonFacade().mergePerson(leadPerson.getUuid(), otherPerson.getUuid(), mergeProperties); + try { + FacadeProvider.getPersonFacade().mergePerson(leadPerson.getUuid(), otherPerson.getUuid(), mergeProperties); + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + } popupWindow.close(); SormasUI.refreshView(); } From d157e7d2f171769978438c877142eb2a2e94a10a Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Wed, 21 Dec 2022 13:21:33 +0100 Subject: [PATCH 019/166] fixes --- .../e2etests/steps/web/application/events/EditEventSteps.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java index 9598538cff8..6c86484478a 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java @@ -639,8 +639,8 @@ public EditEventSteps( fillTitle(collectedEvent.getTitle()); selectSourceType(collectedEvent.getSourceType()); selectTypeOfPlace(collectedEvent.getEventLocation()); - webDriverHelpers.scrollToElement(SAVE_BUTTON); - webDriverHelpers.clickOnWebElementBySelector(SAVE_BUTTON); + webDriverHelpers.scrollToElement(EDIT_EVENT_PAGE_SAVE_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(EDIT_EVENT_PAGE_SAVE_BUTTON); webDriverHelpers.waitUntilElementIsVisibleAndClickable(EVENT_DATA_SAVED_MESSAGE); }); From 85327ddd190d1d2afc6551528001124fc68694f0 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Wed, 21 Dec 2022 13:32:46 +0100 Subject: [PATCH 020/166] fixes --- .../src/test/resources/features/sanity/web/Event.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature index 34773080f6a..85197da9ebc 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature @@ -85,7 +85,7 @@ Feature: Create events And I navigate via URL to last Person created from edit Event page Then I check if event is available at person information - @env_main + @env_main @#checkit Scenario: Create and edit a new event Given I log in as a National User And I click on the Events button from navbar From 75b0c368c6723603b03dd747fa0ac3b6562e8468 Mon Sep 17 00:00:00 2001 From: jenkins Date: Wed, 21 Dec 2022 13:45:21 +0100 Subject: [PATCH 021/166] [GITFLOW]updating poms for 1.79.0-SNAPSHOT development --- sormas-api/pom.xml | 2 +- sormas-app/pom.xml | 2 +- sormas-backend/pom.xml | 2 +- sormas-base/dependencies/serverlibs.pom | 2 +- sormas-base/pom.xml | 2 +- sormas-cargoserver/pom.xml | 2 +- sormas-ear/pom.xml | 2 +- sormas-keycloak-service-provider/pom.xml | 2 +- sormas-rest/pom.xml | 2 +- sormas-ui/pom.xml | 2 +- sormas-widgetset/pom.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/sormas-api/pom.xml b/sormas-api/pom.xml index ec8a91fd49e..5c44b3feb2e 100644 --- a/sormas-api/pom.xml +++ b/sormas-api/pom.xml @@ -2,7 +2,7 @@ de.symeda.sormas sormas-base - 1.78.0-SNAPSHOT + 1.79.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-app/pom.xml b/sormas-app/pom.xml index 6a49b253781..a7f09e49c89 100644 --- a/sormas-app/pom.xml +++ b/sormas-app/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.78.0-SNAPSHOT + 1.79.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-backend/pom.xml b/sormas-backend/pom.xml index 5a7625052ac..d117700d8c6 100644 --- a/sormas-backend/pom.xml +++ b/sormas-backend/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.78.0-SNAPSHOT + 1.79.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-base/dependencies/serverlibs.pom b/sormas-base/dependencies/serverlibs.pom index 91db21e5987..0af96852468 100644 --- a/sormas-base/dependencies/serverlibs.pom +++ b/sormas-base/dependencies/serverlibs.pom @@ -8,7 +8,7 @@ sormas-base de.symeda.sormas - 1.78.0-SNAPSHOT + 1.79.0-SNAPSHOT ../ diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index 8f1cf55d2b9..a55f74dcc14 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -5,7 +5,7 @@ de.symeda.sormas sormas-base pom - 1.78.0-SNAPSHOT + 1.79.0-SNAPSHOT 1.8 diff --git a/sormas-cargoserver/pom.xml b/sormas-cargoserver/pom.xml index 935d51a2397..36ca7fe566d 100644 --- a/sormas-cargoserver/pom.xml +++ b/sormas-cargoserver/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.78.0-SNAPSHOT + 1.79.0-SNAPSHOT ../sormas-base diff --git a/sormas-ear/pom.xml b/sormas-ear/pom.xml index 05d2cab9ca1..15a5ee6012c 100644 --- a/sormas-ear/pom.xml +++ b/sormas-ear/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.78.0-SNAPSHOT + 1.79.0-SNAPSHOT ../sormas-base diff --git a/sormas-keycloak-service-provider/pom.xml b/sormas-keycloak-service-provider/pom.xml index 6c507e70a4e..eb37a2cbdfd 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.78.0-SNAPSHOT + 1.79.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-rest/pom.xml b/sormas-rest/pom.xml index 2798d0cc469..b30a01395b4 100644 --- a/sormas-rest/pom.xml +++ b/sormas-rest/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.78.0-SNAPSHOT + 1.79.0-SNAPSHOT ../sormas-base diff --git a/sormas-ui/pom.xml b/sormas-ui/pom.xml index 04695198254..11cffbcfee3 100644 --- a/sormas-ui/pom.xml +++ b/sormas-ui/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.78.0-SNAPSHOT + 1.79.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-widgetset/pom.xml b/sormas-widgetset/pom.xml index 7ceea1349a7..9de79c5439a 100644 --- a/sormas-widgetset/pom.xml +++ b/sormas-widgetset/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.78.0-SNAPSHOT + 1.79.0-SNAPSHOT ../sormas-base 4.0.0 From 1aaa5bd0d3a527165b6747d5e9511a6f44dc5b27 Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Wed, 21 Dec 2022 13:56:31 +0100 Subject: [PATCH 022/166] fix --- .../pages/application/configuration/CountriesTabPage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java index 5f87cfe9a22..4113ad63839 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java @@ -37,7 +37,7 @@ public class CountriesTabPage { public static final By COUNTRY_GRID_RESULTS_ROWS = By.cssSelector("[role=rowgroup] tr a"); public static final By NUMBER_OF_COUNTRIES = By.xpath( - "//div[@class='v-label v-widget bold v-label-bold vspace-top-none v-label-vspace-top-none align-right v-label-align-right v-label-undef-w']"); + "//div[@class='v-label v-widget v-label-undef-w bold v-label-bold vspace-top-none v-label-vspace-top-none align-right v-label-align-right']"); public static final By COUNTRIES_TABLE_DATA = By.tagName("td"); public static final By COUNTRIES_TABLE_ROW = By.cssSelector("div.v-grid-tablewrapper tbody tr"); public static final By COUNTRIES_NAME_TABLE_ROW = From 9617f3c652a8489d52d96b70b9efa1ebce7c1527 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Wed, 21 Dec 2022 15:04:28 +0100 Subject: [PATCH 023/166] fixes --- .../src/test/resources/features/sanity/web/Event.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature index 85197da9ebc..34773080f6a 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature @@ -85,7 +85,7 @@ Feature: Create events And I navigate via URL to last Person created from edit Event page Then I check if event is available at person information - @env_main @#checkit + @env_main Scenario: Create and edit a new event Given I log in as a National User And I click on the Events button from navbar From a954134bed170715159d1d5cbf64d441d5864038 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Wed, 21 Dec 2022 15:41:48 +0100 Subject: [PATCH 024/166] fixes --- .../src/test/resources/features/sanity/web/mSERS.feature | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/mSERS.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/mSERS.feature index 9d90cfb1870..0bc6f127996 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/mSERS.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/mSERS.feature @@ -87,12 +87,14 @@ Feature: mSERS functionalities Scenario: Test Limited disease user property should not be applied to mSERS aggregated reporting Given I log in as a National User When I click on the mSERS button from navbar + Then I navigate to Report data tab + And I click on the APPLY FILTERS button + And I check aggregate reports and delete them if they are listed When I click on the NEW AGGREGATE REPORT button Then I set Region combobox to "Baden-Württemberg" in Create New Aggregate Report popup And I set District combobox to "LK Alb-Donau-Kreis" in Create New Aggregate Report popup And I fill a new aggregate report with specific data for one disease And I click to save aggregated report - And I navigate to Report data tab Then I select ARI (Acute Respiratory Infections) disease from Disease combobox in mSers directory page And I click on the APPLY FILTERS button And I check if there number of results in grid in mSers directory is 0 From 1cb0d6cf834efbe7a0aef4b5da5544f4f4a99d89 Mon Sep 17 00:00:00 2001 From: jenkins Date: Wed, 21 Dec 2022 16:04:29 +0100 Subject: [PATCH 025/166] [GITFLOW]updating poms for 1.79.0-SNAPSHOT development --- sormas-api/pom.xml | 2 +- sormas-app/pom.xml | 2 +- sormas-backend/pom.xml | 2 +- sormas-base/dependencies/serverlibs.pom | 2 +- sormas-base/pom.xml | 2 +- sormas-cargoserver/pom.xml | 2 +- sormas-ear/pom.xml | 2 +- sormas-keycloak-service-provider/pom.xml | 2 +- sormas-rest/pom.xml | 2 +- sormas-ui/pom.xml | 2 +- sormas-widgetset/pom.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/sormas-api/pom.xml b/sormas-api/pom.xml index ec8a91fd49e..5c44b3feb2e 100644 --- a/sormas-api/pom.xml +++ b/sormas-api/pom.xml @@ -2,7 +2,7 @@ de.symeda.sormas sormas-base - 1.78.0-SNAPSHOT + 1.79.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-app/pom.xml b/sormas-app/pom.xml index 6a49b253781..a7f09e49c89 100644 --- a/sormas-app/pom.xml +++ b/sormas-app/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.78.0-SNAPSHOT + 1.79.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-backend/pom.xml b/sormas-backend/pom.xml index 5a7625052ac..d117700d8c6 100644 --- a/sormas-backend/pom.xml +++ b/sormas-backend/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.78.0-SNAPSHOT + 1.79.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-base/dependencies/serverlibs.pom b/sormas-base/dependencies/serverlibs.pom index 91db21e5987..0af96852468 100644 --- a/sormas-base/dependencies/serverlibs.pom +++ b/sormas-base/dependencies/serverlibs.pom @@ -8,7 +8,7 @@ sormas-base de.symeda.sormas - 1.78.0-SNAPSHOT + 1.79.0-SNAPSHOT ../ diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index 8f1cf55d2b9..a55f74dcc14 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -5,7 +5,7 @@ de.symeda.sormas sormas-base pom - 1.78.0-SNAPSHOT + 1.79.0-SNAPSHOT 1.8 diff --git a/sormas-cargoserver/pom.xml b/sormas-cargoserver/pom.xml index 935d51a2397..36ca7fe566d 100644 --- a/sormas-cargoserver/pom.xml +++ b/sormas-cargoserver/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.78.0-SNAPSHOT + 1.79.0-SNAPSHOT ../sormas-base diff --git a/sormas-ear/pom.xml b/sormas-ear/pom.xml index 05d2cab9ca1..15a5ee6012c 100644 --- a/sormas-ear/pom.xml +++ b/sormas-ear/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.78.0-SNAPSHOT + 1.79.0-SNAPSHOT ../sormas-base diff --git a/sormas-keycloak-service-provider/pom.xml b/sormas-keycloak-service-provider/pom.xml index 6c507e70a4e..eb37a2cbdfd 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.78.0-SNAPSHOT + 1.79.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-rest/pom.xml b/sormas-rest/pom.xml index 2798d0cc469..b30a01395b4 100644 --- a/sormas-rest/pom.xml +++ b/sormas-rest/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.78.0-SNAPSHOT + 1.79.0-SNAPSHOT ../sormas-base diff --git a/sormas-ui/pom.xml b/sormas-ui/pom.xml index 04695198254..11cffbcfee3 100644 --- a/sormas-ui/pom.xml +++ b/sormas-ui/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.78.0-SNAPSHOT + 1.79.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-widgetset/pom.xml b/sormas-widgetset/pom.xml index 7ceea1349a7..9de79c5439a 100644 --- a/sormas-widgetset/pom.xml +++ b/sormas-widgetset/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.78.0-SNAPSHOT + 1.79.0-SNAPSHOT ../sormas-base 4.0.0 From 6b9484831de732410b8f89eabdf0d7e5a311f145 Mon Sep 17 00:00:00 2001 From: jenkins Date: Wed, 21 Dec 2022 16:59:48 +0100 Subject: [PATCH 026/166] [GITFLOW]updating develop poms to master versions to avoid merge conflicts --- sormas-api/pom.xml | 2 +- sormas-app/pom.xml | 2 +- sormas-backend/pom.xml | 2 +- sormas-base/dependencies/serverlibs.pom | 2 +- sormas-base/pom.xml | 2 +- sormas-cargoserver/pom.xml | 2 +- sormas-ear/pom.xml | 2 +- sormas-keycloak-service-provider/pom.xml | 2 +- sormas-rest/pom.xml | 2 +- sormas-ui/pom.xml | 2 +- sormas-widgetset/pom.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/sormas-api/pom.xml b/sormas-api/pom.xml index 5c44b3feb2e..3c5a91dd020 100644 --- a/sormas-api/pom.xml +++ b/sormas-api/pom.xml @@ -2,7 +2,7 @@ de.symeda.sormas sormas-base - 1.79.0-SNAPSHOT + 1.78.0 ../sormas-base 4.0.0 diff --git a/sormas-app/pom.xml b/sormas-app/pom.xml index a7f09e49c89..6431131ba7f 100644 --- a/sormas-app/pom.xml +++ b/sormas-app/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.79.0-SNAPSHOT + 1.78.0 ../sormas-base 4.0.0 diff --git a/sormas-backend/pom.xml b/sormas-backend/pom.xml index d117700d8c6..aad008d2ea3 100644 --- a/sormas-backend/pom.xml +++ b/sormas-backend/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.79.0-SNAPSHOT + 1.78.0 ../sormas-base 4.0.0 diff --git a/sormas-base/dependencies/serverlibs.pom b/sormas-base/dependencies/serverlibs.pom index 0af96852468..eb4d1c29c98 100644 --- a/sormas-base/dependencies/serverlibs.pom +++ b/sormas-base/dependencies/serverlibs.pom @@ -8,7 +8,7 @@ sormas-base de.symeda.sormas - 1.79.0-SNAPSHOT + 1.78.0 ../ diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index a55f74dcc14..6139d6b5cbb 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -5,7 +5,7 @@ de.symeda.sormas sormas-base pom - 1.79.0-SNAPSHOT + 1.78.0 1.8 diff --git a/sormas-cargoserver/pom.xml b/sormas-cargoserver/pom.xml index 36ca7fe566d..4d79eeb4d61 100644 --- a/sormas-cargoserver/pom.xml +++ b/sormas-cargoserver/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.79.0-SNAPSHOT + 1.78.0 ../sormas-base diff --git a/sormas-ear/pom.xml b/sormas-ear/pom.xml index 15a5ee6012c..b989d3adbc5 100644 --- a/sormas-ear/pom.xml +++ b/sormas-ear/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.79.0-SNAPSHOT + 1.78.0 ../sormas-base diff --git a/sormas-keycloak-service-provider/pom.xml b/sormas-keycloak-service-provider/pom.xml index eb37a2cbdfd..419d4cd175a 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.79.0-SNAPSHOT + 1.78.0 ../sormas-base 4.0.0 diff --git a/sormas-rest/pom.xml b/sormas-rest/pom.xml index b30a01395b4..9659eb897fb 100644 --- a/sormas-rest/pom.xml +++ b/sormas-rest/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.79.0-SNAPSHOT + 1.78.0 ../sormas-base diff --git a/sormas-ui/pom.xml b/sormas-ui/pom.xml index 11cffbcfee3..86bb6c72e1f 100644 --- a/sormas-ui/pom.xml +++ b/sormas-ui/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.79.0-SNAPSHOT + 1.78.0 ../sormas-base 4.0.0 diff --git a/sormas-widgetset/pom.xml b/sormas-widgetset/pom.xml index 9de79c5439a..0b45879e1ce 100644 --- a/sormas-widgetset/pom.xml +++ b/sormas-widgetset/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.79.0-SNAPSHOT + 1.78.0 ../sormas-base 4.0.0 From 01b23a9be5212c0e9ffca390614d6efdc4165bb8 Mon Sep 17 00:00:00 2001 From: jenkins Date: Wed, 21 Dec 2022 16:59:51 +0100 Subject: [PATCH 027/166] [GITFLOW]Updating develop poms back to pre merge state --- sormas-api/pom.xml | 2 +- sormas-app/pom.xml | 2 +- sormas-backend/pom.xml | 2 +- sormas-base/dependencies/serverlibs.pom | 2 +- sormas-base/pom.xml | 2 +- sormas-cargoserver/pom.xml | 2 +- sormas-ear/pom.xml | 2 +- sormas-keycloak-service-provider/pom.xml | 2 +- sormas-rest/pom.xml | 2 +- sormas-ui/pom.xml | 2 +- sormas-widgetset/pom.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/sormas-api/pom.xml b/sormas-api/pom.xml index 3c5a91dd020..5c44b3feb2e 100644 --- a/sormas-api/pom.xml +++ b/sormas-api/pom.xml @@ -2,7 +2,7 @@ de.symeda.sormas sormas-base - 1.78.0 + 1.79.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-app/pom.xml b/sormas-app/pom.xml index 6431131ba7f..a7f09e49c89 100644 --- a/sormas-app/pom.xml +++ b/sormas-app/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.78.0 + 1.79.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-backend/pom.xml b/sormas-backend/pom.xml index aad008d2ea3..d117700d8c6 100644 --- a/sormas-backend/pom.xml +++ b/sormas-backend/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.78.0 + 1.79.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-base/dependencies/serverlibs.pom b/sormas-base/dependencies/serverlibs.pom index eb4d1c29c98..0af96852468 100644 --- a/sormas-base/dependencies/serverlibs.pom +++ b/sormas-base/dependencies/serverlibs.pom @@ -8,7 +8,7 @@ sormas-base de.symeda.sormas - 1.78.0 + 1.79.0-SNAPSHOT ../ diff --git a/sormas-base/pom.xml b/sormas-base/pom.xml index 6139d6b5cbb..a55f74dcc14 100644 --- a/sormas-base/pom.xml +++ b/sormas-base/pom.xml @@ -5,7 +5,7 @@ de.symeda.sormas sormas-base pom - 1.78.0 + 1.79.0-SNAPSHOT 1.8 diff --git a/sormas-cargoserver/pom.xml b/sormas-cargoserver/pom.xml index 4d79eeb4d61..36ca7fe566d 100644 --- a/sormas-cargoserver/pom.xml +++ b/sormas-cargoserver/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.78.0 + 1.79.0-SNAPSHOT ../sormas-base diff --git a/sormas-ear/pom.xml b/sormas-ear/pom.xml index b989d3adbc5..15a5ee6012c 100644 --- a/sormas-ear/pom.xml +++ b/sormas-ear/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.78.0 + 1.79.0-SNAPSHOT ../sormas-base diff --git a/sormas-keycloak-service-provider/pom.xml b/sormas-keycloak-service-provider/pom.xml index 419d4cd175a..eb37a2cbdfd 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.78.0 + 1.79.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-rest/pom.xml b/sormas-rest/pom.xml index 9659eb897fb..b30a01395b4 100644 --- a/sormas-rest/pom.xml +++ b/sormas-rest/pom.xml @@ -3,7 +3,7 @@ de.symeda.sormas sormas-base - 1.78.0 + 1.79.0-SNAPSHOT ../sormas-base diff --git a/sormas-ui/pom.xml b/sormas-ui/pom.xml index 86bb6c72e1f..11cffbcfee3 100644 --- a/sormas-ui/pom.xml +++ b/sormas-ui/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.78.0 + 1.79.0-SNAPSHOT ../sormas-base 4.0.0 diff --git a/sormas-widgetset/pom.xml b/sormas-widgetset/pom.xml index 0b45879e1ce..9de79c5439a 100644 --- a/sormas-widgetset/pom.xml +++ b/sormas-widgetset/pom.xml @@ -3,7 +3,7 @@ sormas-base de.symeda.sormas - 1.78.0 + 1.79.0-SNAPSHOT ../sormas-base 4.0.0 From 9adfc1ef07a5379f36d2dd54dba86335d1c41a79 Mon Sep 17 00:00:00 2001 From: dinua Date: Thu, 22 Dec 2022 11:43:32 +0200 Subject: [PATCH 028/166] #9360 pseudonymizer values --- .../porthealthinfo/PortHealthInfoDto.java | 23 +++++++++++++++++ .../PortHealthInfoFacadeEjb.java | 25 +++++++++++++++++-- .../porthealthinfo/PortHealthInfoService.java | 12 +++++++-- .../pointofentry/PointOfEntryFacadeEjb.java | 3 ++- .../symeda/sormas/ui/caze/CaseController.java | 3 ++- .../porthealthinfo/PortHealthInfoForm.java | 18 ++++++++++--- 6 files changed, 75 insertions(+), 9 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/caze/porthealthinfo/PortHealthInfoDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/caze/porthealthinfo/PortHealthInfoDto.java index d29c266ddf7..7220bdb6ee6 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/caze/porthealthinfo/PortHealthInfoDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/caze/porthealthinfo/PortHealthInfoDto.java @@ -10,6 +10,7 @@ import de.symeda.sormas.api.i18n.Validations; import de.symeda.sormas.api.utils.DataHelper; import de.symeda.sormas.api.utils.FieldConstraints; +import de.symeda.sormas.api.utils.SensitiveData; import de.symeda.sormas.api.utils.YesNoUnknown; @DependingOnFeatureType(featureType = FeatureType.CASE_SURVEILANCE) @@ -43,49 +44,71 @@ public class PortHealthInfoDto extends EntityDto { public static final String DETAILS = "details"; // Airport + @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String airlineName; + @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String flightNumber; + @SensitiveData private Date departureDateTime; + @SensitiveData private Date arrivalDateTime; + @SensitiveData private YesNoUnknown freeSeating; + @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String seatNumber; + @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String departureAirport; + @SensitiveData private Integer numberOfTransitStops; + @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String transitStopDetails1; + @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String transitStopDetails2; + @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String transitStopDetails3; + @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String transitStopDetails4; + @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String transitStopDetails5; // Seaport + @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String vesselName; + @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String vesselDetails; + @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String portOfDeparture; + @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String lastPortOfCall; // Ground Crossing + @SensitiveData private ConveyanceType conveyanceType; + @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String conveyanceTypeDetails; + @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String departureLocation; + @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String finalDestination; // Other + @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_BIG, message = Validations.textTooLong) private String details; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoFacadeEjb.java index 602146f8a42..b3607e5165d 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoFacadeEjb.java @@ -1,5 +1,6 @@ package de.symeda.sormas.backend.caze.porthealthinfo; +import javax.ejb.EJB; import javax.ejb.LocalBean; import javax.ejb.Stateless; import javax.persistence.EntityManager; @@ -13,9 +14,13 @@ import de.symeda.sormas.api.caze.porthealthinfo.PortHealthInfoDto; import de.symeda.sormas.api.caze.porthealthinfo.PortHealthInfoFacade; +import de.symeda.sormas.api.i18n.Captions; +import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.backend.caze.Case; +import de.symeda.sormas.backend.user.UserService; import de.symeda.sormas.backend.util.DtoHelper; import de.symeda.sormas.backend.util.ModelConstants; +import de.symeda.sormas.backend.util.Pseudonymizer; import de.symeda.sormas.backend.util.QueryHelper; @Stateless(name = "PortHealthInfoFacade") @@ -23,7 +28,11 @@ public class PortHealthInfoFacadeEjb implements PortHealthInfoFacade { @PersistenceContext(unitName = ModelConstants.PERSISTENCE_UNIT_NAME) private EntityManager em; - + @EJB + private UserService userService; + @EJB + private PortHealthInfoService portHealthInfoService; + public static PortHealthInfoDto toDto(PortHealthInfo source) { if (source == null) { return null; @@ -96,8 +105,20 @@ public PortHealthInfoDto getByCaseUuid(String caseUuid) { cq.select(portHealthJoin); cq.where(cb.equal(root.get(Case.UUID), caseUuid)); + PortHealthInfo portHealthInfo = QueryHelper.getSingleResult(em, cq); + + return toPseudonymizedDto(portHealthInfo); + } + + private PortHealthInfoDto toPseudonymizedDto(PortHealthInfo portHealthInfo) { + Pseudonymizer pseudonymizer = createPseudonymizer(); + PortHealthInfoDto portHealthInfoDto = toDto(portHealthInfo); + pseudonymizer.pseudonymizeDto(PortHealthInfoDto.class, portHealthInfoDto, portHealthInfoService.inJurisdictionOrOwned(portHealthInfo), null); + return portHealthInfoDto; + } - return QueryHelper.getSingleResult(em, cq, PortHealthInfoFacadeEjb::toDto); + private Pseudonymizer createPseudonymizer() { + return Pseudonymizer.getDefault(userService::hasRight, I18nProperties.getCaption(Captions.inaccessibleValue)); } @LocalBean diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoService.java index 4ad8e43d1e1..900ffcd2a23 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoService.java @@ -2,15 +2,23 @@ import javax.ejb.LocalBean; import javax.ejb.Stateless; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.From; +import javax.persistence.criteria.Predicate; -import de.symeda.sormas.backend.common.BaseAdoService; +import de.symeda.sormas.backend.common.AdoServiceWithUserFilterAndJurisdiction; @Stateless @LocalBean -public class PortHealthInfoService extends BaseAdoService { +public class PortHealthInfoService extends AdoServiceWithUserFilterAndJurisdiction { public PortHealthInfoService() { super(PortHealthInfo.class); } + @Override + public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { + return null; + } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryFacadeEjb.java index ad70d4a92f2..885f2bbcc86 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryFacadeEjb.java @@ -233,8 +233,9 @@ public PointOfEntryDto getByCaseUuid(String caseUuid) { cq.select(pointOfEntryJoin); cq.where(cb.equal(root.get(Case.UUID), caseUuid)); + PointOfEntry pointOfEntry = QueryHelper.getSingleResult(em, cq); - return QueryHelper.getSingleResult(em, cq, this::toDto); + return toPseudonymizedDto(pointOfEntry); } @Override diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java index f2d1a289de7..fa7a0dc71af 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java @@ -1340,7 +1340,8 @@ public CommitDiscardWrapperComponent getPortHealthInfoCompon } PointOfEntryDto pointOfEntry = FacadeProvider.getPointOfEntryFacade().getByCaseUuid(caseUuid); - PortHealthInfoForm form = new PortHealthInfoForm(pointOfEntry, caze.getPointOfEntryDetails()); + PortHealthInfoForm form = + new PortHealthInfoForm(pointOfEntry, caze.getPointOfEntryDetails(), caze.isPseudonymized(), caze.isInJurisdiction()); form.setValue(getPortHealthInfo(caze)); final CommitDiscardWrapperComponent component = new CommitDiscardWrapperComponent( diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/porthealthinfo/PortHealthInfoForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/porthealthinfo/PortHealthInfoForm.java index e7037b1402e..ac6f2fe18ac 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/porthealthinfo/PortHealthInfoForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/porthealthinfo/PortHealthInfoForm.java @@ -11,6 +11,7 @@ import com.vaadin.v7.ui.TextArea; import com.vaadin.v7.ui.TextField; +import de.symeda.sormas.api.FacadeProvider; import de.symeda.sormas.api.caze.CaseDataDto; import de.symeda.sormas.api.caze.porthealthinfo.ConveyanceType; import de.symeda.sormas.api.caze.porthealthinfo.PortHealthInfoDto; @@ -22,6 +23,9 @@ import de.symeda.sormas.api.infrastructure.pointofentry.PointOfEntryReferenceDto; import de.symeda.sormas.api.utils.DataHelper; import de.symeda.sormas.api.utils.YesNoUnknown; +import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; +import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; +import de.symeda.sormas.ui.UserProvider; import de.symeda.sormas.ui.utils.AbstractEditForm; import de.symeda.sormas.ui.utils.DateComparisonValidator; import de.symeda.sormas.ui.utils.DateTimeField; @@ -70,9 +74,13 @@ public class PortHealthInfoForm extends AbstractEditForm { private PointOfEntryDto pointOfEntry; private String pointOfEntryDetails; - public PortHealthInfoForm(PointOfEntryDto pointOfEntry, String pointOfEntryDetails) { - - super(PortHealthInfoDto.class, PortHealthInfoDto.I18N_PREFIX); + public PortHealthInfoForm(PointOfEntryDto pointOfEntry, String pointOfEntryDetails, boolean isPseudonymized, boolean inJurisdiction) { + super( + PortHealthInfoDto.class, + PortHealthInfoDto.I18N_PREFIX, + false, + FieldVisibilityCheckers.withCountry(FacadeProvider.getConfigFacade().getCountryLocale()), + UiFieldAccessCheckers.forDataAccessLevel(UserProvider.getCurrent().getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized)); this.pointOfEntry = pointOfEntry; this.pointOfEntryDetails = pointOfEntryDetails; @@ -113,6 +121,10 @@ protected void addFields() { addOtherFields(); break; } + + // Set initial visibilities & accesses + initializeVisibilitiesAndAllowedVisibilities(); + initializeAccessAndAllowedAccesses(); } private void addAirportFields() { From 1f5d977cc66c99ecc76db7a4fda98c1d8317268d Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Thu, 22 Dec 2022 11:45:52 +0100 Subject: [PATCH 029/166] fix --- .../steps/web/application/events/EditEventSteps.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java index 9598538cff8..0d3b5b4266a 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java @@ -747,11 +747,12 @@ public EditEventSteps( When( "I click on save button in Add Participant form", () -> { - webDriverHelpers.waitUntilIdentifiedElementIsVisibleAndClickable(SAVE_BUTTON); + webDriverHelpers.waitUntilIdentifiedElementIsVisibleAndClickable( + EDIT_EVENT_PAGE_SAVE_BUTTON); TimeUnit.SECONDS.sleep(2); // needed for button to be available int attempts = 0; do { - webDriverHelpers.clickOnWebElementBySelector(SAVE_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(EDIT_EVENT_PAGE_SAVE_BUTTON); attempts++; } while (attempts < 5 && webDriverHelpers.isElementPresent(By.cssSelector(".v-window-wrap"))); From fec839e138433e3b08ca735f8f207e339bae0ee0 Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Thu, 22 Dec 2022 13:28:10 +0100 Subject: [PATCH 030/166] fix --- .../steps/web/application/events/EventDirectorySteps.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EventDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EventDirectorySteps.java index 1e2c85a081a..2162e6aa017 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EventDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EventDirectorySteps.java @@ -456,6 +456,8 @@ public EventDirectorySteps( "I apply {string} to combobox on Event Directory Page", (String eventParameter) -> { webDriverHelpers.selectFromCombobox(EVENT_DISPLAY_COMBOBOX, eventParameter); + TimeUnit.SECONDS.sleep(5); // wait for reaction + webDriverHelpers.waitForPageLoadingSpinnerToDisappear(40); }); And( "I apply Date type filter to {string} on Event directory page", @@ -819,11 +821,13 @@ public EventDirectorySteps( When( "I search for specific event by uuid in event directory", () -> { + TimeUnit.SECONDS.sleep(2); + webDriverHelpers.waitForPageLoadingSpinnerToDisappear(40); final String eventUuid = CreateNewEventSteps.newEvent.getUuid(); webDriverHelpers.waitUntilIdentifiedElementIsVisibleAndClickable( SEARCH_EVENT_BY_FREE_TEXT_INPUT, 20); webDriverHelpers.fillAndSubmitInWebElement(SEARCH_EVENT_BY_FREE_TEXT_INPUT, eventUuid); - webDriverHelpers.clickOnWebElementBySelector(APPLY_FILTER); + // webDriverHelpers.clickOnWebElementBySelector(APPLY_FILTER); TimeUnit.SECONDS.sleep(2); // wait for filter webDriverHelpers.waitForPageLoadingSpinnerToDisappear(100); }); From b4b33aa2f463334ea4b335c0ee4b4e31cb8b1409 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Thu, 22 Dec 2022 14:58:04 +0100 Subject: [PATCH 031/166] fixes --- .../steps/web/application/cases/CreateNewCaseSteps.java | 2 +- .../steps/web/application/events/EditEventSteps.java | 6 ++++++ .../src/test/resources/features/sanity/web/Case.feature | 4 ++-- .../src/test/resources/features/sanity/web/Contacts.feature | 2 +- .../src/test/resources/features/sanity/web/Event.feature | 6 +++--- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CreateNewCaseSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CreateNewCaseSteps.java index b2b4f68d410..4592cd2e7c1 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CreateNewCaseSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CreateNewCaseSteps.java @@ -744,7 +744,7 @@ public CreateNewCaseSteps( webDriverHelpers.waitForPageLoadingSpinnerToDisappear(30); }); When( - "^I check if National Health Id, Nickname and Passport number appear in Pick or create person popup$", + "^I check if National Health Id, Nickname and Passport number do not appear in Pick or create person popup$", () -> { softly.assertEquals( false, webDriverHelpers.isElementVisibleWithTimeout(NICKNAME_ATTRIBUTE, 2)); diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java index 2da5b6e0639..896486a1ea8 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java @@ -1974,6 +1974,12 @@ public EditEventSteps( () -> { webDriverHelpers.fillAndSubmitInWebElement(SEARCH_EVENT_BY_FREE_TEXT_INPUT, eventUUID); }); + + And( + "^I save Add participant form$", + () -> { + webDriverHelpers.clickOnWebElementBySelector(SAVE_BUTTON_FOR_POPUP_WINDOWS); + }); } private String collectEventParticipantUuid() { 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 643709c17f9..49d85ccd972 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 @@ -1156,7 +1156,7 @@ Feature: Case end to end tests And I click on the NEW CASE button When I fill a new case form with same person details for DE version And I click on Save button in Case form - Then I check if National Health Id, Nickname and Passport number appear in Pick or create person popup + Then I check if National Health Id, Nickname and Passport number do not appear in Pick or create person popup And I open the Case Contacts tab And I click on the NEW CONTACT button And I fill a new contact form with same person data for DE version @@ -1165,7 +1165,7 @@ Feature: Case end to end tests And I click on the NEW CONTACT button And I fill a new contact form with same person data for DE version And I click on SAVE new contact case button - Then I check if National Health Id, Nickname and Passport number appear in Pick or create person popup + Then I check if National Health Id, Nickname and Passport number do not appear in Pick or create person popup @tmsLink=SORDEV-8413 @env_main Scenario: Test Hide specific enum values based on the related disease diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Contacts.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Contacts.feature index 27159bbe75c..841a9dbb349 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Contacts.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Contacts.feature @@ -756,7 +756,7 @@ Feature: Contacts end to end tests And I click on the NEW CONTACT button And I fill a new contact form with same person data for DE version And I click on SAVE new contact case button - And I check if National Health Id, Nickname and Passport number appear in Pick or create person popup + And I check if National Health Id, Nickname and Passport number do not appear in Pick or create person popup @tmsLink=SORDEV-6434 @env_main Scenario: Check if username shows up in visit origin diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature index 34773080f6a..18ec4a9be16 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature @@ -713,12 +713,12 @@ Feature: Create events Then I navigate to EVENT PARTICIPANT from edit event page And I click on Add Participant button Then I add Participant to an Event with same person data - And I click on save button in Add Participant form + And I save Add participant form Then I navigate to EVENT PARTICIPANT from edit event page And I click on Add Participant button Then I add Participant to an Event with same person data - And I click on save button in Add Participant form - And I check if National Health Id, Nickname and Passport number appear in Pick or create person popup + And I save Add participant form + And I check if National Health Id, Nickname and Passport number do not appear in Pick or create person popup @env_main @tmsLink=SORDEV-7460 Scenario: Test Extend the exposure and event startDate and endDate to include a startTime and endTime From af5fcf8fb612bf89b1bdca217c6010c23e8bfec1 Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Thu, 22 Dec 2022 15:33:57 +0100 Subject: [PATCH 032/166] fix --- .../steps/web/application/events/EventDirectorySteps.java | 6 ++++-- .../src/test/resources/features/sanity/web/Event.feature | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EventDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EventDirectorySteps.java index 2162e6aa017..9ea5ef5aeca 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EventDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EventDirectorySteps.java @@ -826,8 +826,10 @@ public EventDirectorySteps( final String eventUuid = CreateNewEventSteps.newEvent.getUuid(); webDriverHelpers.waitUntilIdentifiedElementIsVisibleAndClickable( SEARCH_EVENT_BY_FREE_TEXT_INPUT, 20); - webDriverHelpers.fillAndSubmitInWebElement(SEARCH_EVENT_BY_FREE_TEXT_INPUT, eventUuid); - // webDriverHelpers.clickOnWebElementBySelector(APPLY_FILTER); + webDriverHelpers.fillInWebElement(SEARCH_EVENT_BY_FREE_TEXT_INPUT, eventUuid); + TimeUnit.SECONDS.sleep(2); + webDriverHelpers.waitForPageLoadingSpinnerToDisappear(100); + webDriverHelpers.clickOnWebElementBySelector(APPLY_FILTER); TimeUnit.SECONDS.sleep(2); // wait for filter webDriverHelpers.waitForPageLoadingSpinnerToDisappear(100); }); diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature index 34773080f6a..0a677a8e866 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature @@ -1113,7 +1113,7 @@ Feature: Create events And I check if General comment on event participant edit page is disabled And I check if Involvement description input on event participant edit page is disabled - @tmsLink=SORDEV-9792 @env_de + @tmsLink=SORDEV-9792 @env_de @testIt Scenario: Test CoreAdo: Introduce "end of processing date" for events Given I log in as a Admin User And I click on the Events button from navbar @@ -1142,7 +1142,7 @@ Feature: Create events And I fill De-Archive event popup with test automation reason And I click on the Events button from navbar And I apply "Aktive Ereignisse" to combobox on Event Directory Page - And I search for specific event by uuid in event directory + # And I search for specific event by uuid in event directory And I check that number of displayed Event results is 1 @tmsLink=SORDEV-9792 @env_de From 4faeab23ca37bd09480b19eda519b3552f98c1ec Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Thu, 22 Dec 2022 16:06:47 +0100 Subject: [PATCH 033/166] fix --- .../src/test/resources/features/sanity/web/Event.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature index 0a677a8e866..fcf994780bf 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Event.feature @@ -1113,7 +1113,7 @@ Feature: Create events And I check if General comment on event participant edit page is disabled And I check if Involvement description input on event participant edit page is disabled - @tmsLink=SORDEV-9792 @env_de @testIt + @tmsLink=SORDEV-9792 @env_de Scenario: Test CoreAdo: Introduce "end of processing date" for events Given I log in as a Admin User And I click on the Events button from navbar From ef7228fdc7c4e29753b60a3a6dc3cccbfb8944b1 Mon Sep 17 00:00:00 2001 From: Frank T Date: Thu, 22 Dec 2022 16:07:39 +0100 Subject: [PATCH 034/166] #10395 make 'Facility name' field not mandatory in Case Line Listing (#11237) --- .../ui/caze/components/linelisting/LineListingLayout.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/components/linelisting/LineListingLayout.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/components/linelisting/LineListingLayout.java index 1474ae5f0a6..bed3da7d6ff 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/components/linelisting/LineListingLayout.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/components/linelisting/LineListingLayout.java @@ -456,11 +456,10 @@ public CaseLineLayout(int lineIndex) { binder.forField(facility).asRequired().bind(CaseLineDto.FACILITY); facilityDetails = new TextField(); facilityDetails.setId("lineListingFacilityDetails_" + lineIndex); + CssStyles.style(facilityDetails, CssStyles.SOFT_REQUIRED); facilityDetails.setVisible(false); updateFacilityFields(facility, facilityDetails); - binder.forField(facilityDetails) - .asRequired(new FieldVisibleAndNotEmptyValidator<>(I18nProperties.getString(Strings.errorFieldValidationFailed))) - .bind(CaseLineDto.FACILITY_DETAILS); + binder.forField(facilityDetails).bind(CaseLineDto.FACILITY_DETAILS); person = new PersonField(); person.setId("lineListingPerson_" + lineIndex); From 7a9ba5b493765076ad1c2e60ededf6c4f164bfb9 Mon Sep 17 00:00:00 2001 From: valentinmikleuvg <112615459+valentinmikleuvg@users.noreply.github.com> Date: Thu, 22 Dec 2022 18:03:51 +0200 Subject: [PATCH 035/166] #9811-TravelEntryDataForm: DirtyCheckPopup is triggered twice (#11248) removed the second trigger for DirtyCheckPopup --- .../de/symeda/sormas/ui/travelentry/TravelEntryController.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryController.java index 2fb7e801a0d..edc1d0acbe9 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryController.java @@ -159,8 +159,6 @@ public CommitDiscardWrapperComponent getTravelEntryDataEdit } }); - editComponent.addDiscardListener(() -> travelEntryEditForm.onDiscard()); - // Initialize 'Delete' button if (UserProvider.getCurrent().hasUserRight(UserRight.TRAVEL_ENTRY_DELETE)) { editComponent.addDeleteWithReasonOrUndeleteListener( From 9d1feb961e370e190797f3872b0e92e8d0fe2bb2 Mon Sep 17 00:00:00 2001 From: dinua Date: Fri, 23 Dec 2022 10:11:19 +0200 Subject: [PATCH 036/166] #8734 fix bug --- .../java/de/symeda/sormas/ui/contact/ContactVisitsView.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactVisitsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactVisitsView.java index 5a91afdb98e..4e5328b3400 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactVisitsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactVisitsView.java @@ -160,6 +160,9 @@ public void run() { final ContactDto contactDto = FacadeProvider.getContactFacade().getByUuid(this.getContactRef().getUuid()); if (contactDto.getResultingCase() != null) { newButton.setEnabled(false); + if (topLayout.getComponentCount() == 1) { + topLayout.setExpandRatio(newButton, 1); + } final Label label = new Label(VaadinIcons.INFO_CIRCLE.getHtml(), ContentMode.HTML); label.setDescription(I18nProperties.getString(Strings.infoContactAlreadyConvertedToCase)); topLayout.addComponent(label); From 27ea9e3592128ff5ece0ac1fe0149732418ec1e8 Mon Sep 17 00:00:00 2001 From: dinua Date: Fri, 23 Dec 2022 10:23:53 +0200 Subject: [PATCH 037/166] #9360 fix test --- .../backend/infrastructure/PortHealthInfoFacadeEjbTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PortHealthInfoFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PortHealthInfoFacadeEjbTest.java index 47c310b6d61..54a1961a6a0 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PortHealthInfoFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PortHealthInfoFacadeEjbTest.java @@ -3,6 +3,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import de.symeda.sormas.api.i18n.Captions; +import de.symeda.sormas.api.i18n.I18nProperties; import org.junit.jupiter.api.Test; import de.symeda.sormas.api.caze.CaseDataDto; @@ -33,6 +35,6 @@ public void testGetPortHealthInfoByCaseUuid() { PortHealthInfoDto healthInfoDto = getPortHealthInfoFacade().getByCaseUuid(caseDataDto.getUuid()); assertNotNull(healthInfoDto); assertEquals(portHealthInfoDto.getUuid(), healthInfoDto.getUuid()); - assertEquals(portHealthInfoDto.getAirlineName(), healthInfoDto.getAirlineName()); + assertEquals(I18nProperties.getCaption(Captions.inaccessibleValue), healthInfoDto.getAirlineName()); } } From 4b11f94f10fcf6f302381f2db0a7f9a68b4a2ad1 Mon Sep 17 00:00:00 2001 From: valentinmikleuvg <112615459+valentinmikleuvg@users.noreply.github.com> Date: Fri, 23 Dec 2022 12:05:41 +0200 Subject: [PATCH 038/166] #10033-User Role - When a role is being enable to have at least one right selected (#11228) after the user role was created, a warning message saying that the user role was created without rights is displayed --- .../src/main/java/de/symeda/sormas/api/i18n/Strings.java | 1 + sormas-api/src/main/resources/strings.properties | 2 ++ .../java/de/symeda/sormas/ui/user/UserRoleController.java | 4 ++++ 3 files changed, 7 insertions(+) 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 14083abf1f8..6669f54f3ee 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 @@ -1256,6 +1256,7 @@ public interface Strings { String messageUploadSuccessful = "messageUploadSuccessful"; String messageUserRightsExportFailed = "messageUserRightsExportFailed"; String messageUserRoleCombination = "messageUserRoleCombination"; + String messageUserRoleHasNoRights = "messageUserRoleHasNoRights"; String messageUserRoleSaved = "messageUserRoleSaved"; String messageUserRoleUnusableForLogin = "messageUserRoleUnusableForLogin"; String messageUsersDisabled = "messageUsersDisabled"; diff --git a/sormas-api/src/main/resources/strings.properties b/sormas-api/src/main/resources/strings.properties index 6fc10c29777..7aaa97b1a0f 100644 --- a/sormas-api/src/main/resources/strings.properties +++ b/sormas-api/src/main/resources/strings.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # Notifications notificationCaseClassificationChanged = The classification of case %s has changed to %s. diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserRoleController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserRoleController.java index 0df3457bec0..80c5847a749 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserRoleController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserRoleController.java @@ -66,6 +66,10 @@ public CommitDiscardWrapperComponent getUserRoleCreateCompon UserRoleDto dto = createForm.getValue(); FacadeProvider.getUserRoleFacade().saveUserRole(dto); + Notification.show( + I18nProperties.getString(Strings.messageUserRoleSaved), + I18nProperties.getString(Strings.messageUserRoleHasNoRights), + Notification.Type.WARNING_MESSAGE); editData(dto.getUuid()); } }); From 11cc6a84375d4e307d5fda98a5268bc9ac60cbdc Mon Sep 17 00:00:00 2001 From: valentinmikleuvg <112615459+valentinmikleuvg@users.noreply.github.com> Date: Fri, 23 Dec 2022 12:43:09 +0200 Subject: [PATCH 039/166] #3842 add task type filter to task management (#11164) * #3842 - Add task type filter to Task Management * #3842 Add task type filter to Task Management : added the dependency between task context and task type Co-authored-by: Carina Paul --- .../java/de/symeda/sormas/api/task/TaskCriteria.java | 4 ++++ .../de/symeda/sormas/ui/task/TaskGridFilterForm.java | 11 ++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/task/TaskCriteria.java b/sormas-api/src/main/java/de/symeda/sormas/api/task/TaskCriteria.java index 027bf73df2b..adc57e44348 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/task/TaskCriteria.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/task/TaskCriteria.java @@ -91,6 +91,10 @@ public TaskType getTaskType() { return taskType; } + public void setTaskType(TaskType taskType) { + this.taskType = taskType; + } + public TaskCriteria assigneeUser(UserReferenceDto assigneeUser) { this.assigneeUser = assigneeUser; return this; diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskGridFilterForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskGridFilterForm.java index b6b028fa8b3..c921ff9b47c 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskGridFilterForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskGridFilterForm.java @@ -18,9 +18,11 @@ import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.i18n.Strings; import de.symeda.sormas.api.infrastructure.region.RegionReferenceDto; +import de.symeda.sormas.api.task.TaskContext; import de.symeda.sormas.api.task.TaskCriteria; import de.symeda.sormas.api.task.TaskDateType; import de.symeda.sormas.api.task.TaskIndexDto; +import de.symeda.sormas.api.task.TaskType; import de.symeda.sormas.api.user.UserDto; import de.symeda.sormas.api.utils.DateFilterOption; import de.symeda.sormas.api.utils.DateHelper; @@ -54,6 +56,7 @@ protected String[] getMainFilterLocators() { return new String[] { TaskIndexDto.TASK_CONTEXT, TaskIndexDto.TASK_STATUS, + TaskIndexDto.TASK_TYPE, TaskIndexDto.REGION, TaskIndexDto.DISTRICT, TaskCriteria.FREE_TEXT }; @@ -66,8 +69,14 @@ protected String createMoreFiltersHtmlLayout() { @Override protected void addFields() { - addField(FieldConfiguration.pixelSized(TaskIndexDto.TASK_CONTEXT, 140)); + final ComboBox contextField = addField(FieldConfiguration.pixelSized(TaskIndexDto.TASK_CONTEXT, 140)); addField(FieldConfiguration.pixelSized(TaskIndexDto.TASK_STATUS, 140)); + final ComboBox typeField = addField(FieldConfiguration.pixelSized(TaskIndexDto.TASK_TYPE, 140)); + + contextField.addValueChangeListener(e -> { + TaskContext taskContext = (TaskContext) e.getProperty().getValue(); + FieldHelper.updateEnumData(typeField, TaskType.getTaskTypes(taskContext)); + }); final UserDto user = currentUserDto(); if (user.getDistrict() == null) { From ff9d2276ae0144094b4a7e57c48291d052301071 Mon Sep 17 00:00:00 2001 From: Bartha Barna Date: Fri, 23 Dec 2022 14:34:13 +0200 Subject: [PATCH 040/166] #11002 reuse joins for AbstractCoreAdoService.addChangeDates (#11242) Co-authored-by: Stefan Kock --- .../backend/campaign/CampaignService.java | 7 ++- .../sormas/backend/caze/CaseFacadeEjb.java | 4 +- .../symeda/sormas/backend/caze/CaseJoins.java | 37 +++++++++++--- .../sormas/backend/caze/CaseService.java | 50 ++++++++----------- .../common/AbstractCoreAdoService.java | 12 +++-- .../backend/common/AbstractCoreFacadeEjb.java | 2 +- .../sormas/backend/common/BaseAdoService.java | 4 ++ .../sormas/backend/contact/ContactJoins.java | 2 +- .../backend/contact/ContactService.java | 37 ++++++++------ .../sormas/backend/event/EventJoins.java | 10 ++++ .../event/EventParticipantService.java | 18 ++++--- .../sormas/backend/event/EventService.java | 37 +++++++------- .../immunization/ImmunizationJoins.java | 10 ++++ .../immunization/ImmunizationService.java | 23 ++++++--- .../AbstractSormasToSormasInterface.java | 3 +- .../caze/SormasToSormasCaseFacadeEjb.java | 3 +- .../SormasToSormasContactFacadeEjb.java | 3 +- .../event/SormasToSormasEventFacadeEjb.java | 3 +- .../services/BaseTravelEntryService.java | 19 ++++--- 19 files changed, 182 insertions(+), 102 deletions(-) diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java index 15d77cd4416..ec774958dbb 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java @@ -19,7 +19,7 @@ @Stateless @LocalBean -public class CampaignService extends AbstractCoreAdoService { +public class CampaignService extends AbstractCoreAdoService { public CampaignService() { super(Campaign.class); @@ -31,6 +31,11 @@ protected Predicate createUserFilterInternal(CriteriaBuilder cb, CriteriaQuery c return createUserFilter(new CampaignQueryContext(cb, cq, from)); } + @Override + protected CampaignJoins toJoins(From adoPath) { + return new CampaignJoins(adoPath); + } + public Predicate createUserFilter(CampaignQueryContext queryContext) { // A user who has access to CampaignView can read all campaigns return null; 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 7eb6f037411..0d94a48df30 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 @@ -3818,11 +3818,13 @@ public void archiveAllArchivableCases(int daysAfterCaseGetsArchived, LocalDate r CriteriaQuery cq = cb.createQuery(String.class); Root from = cq.from(Case.class); + CaseQueryContext qc = new CaseQueryContext(cb, cq, from); + Timestamp notChangedTimestamp = Timestamp.valueOf(notChangedSince.atStartOfDay()); cq.where( cb.equal(from.get(Case.ARCHIVED), false), cb.equal(from.get(Case.DELETED), false), - cb.not(service.createChangeDateFilter(cb, from, notChangedTimestamp, true))); + cb.not(service.createChangeDateFilter(cb, qc.getJoins(), notChangedTimestamp, true))); cq.select(from.get(Case.UUID)).distinct(true); List caseUuids = em.createQuery(cq).getResultList(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseJoins.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseJoins.java index c1c436f948c..18ca771d049 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseJoins.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseJoins.java @@ -21,6 +21,7 @@ import javax.persistence.criteria.Join; import javax.persistence.criteria.JoinType; +import de.symeda.sormas.backend.caze.surveillancereport.SurveillanceReport; import de.symeda.sormas.backend.clinicalcourse.ClinicalCourse; import de.symeda.sormas.backend.clinicalcourse.HealthConditions; import de.symeda.sormas.backend.common.QueryJoins; @@ -44,6 +45,7 @@ import de.symeda.sormas.backend.sormastosormas.share.outgoing.SormasToSormasShareInfo; import de.symeda.sormas.backend.symptoms.Symptoms; import de.symeda.sormas.backend.user.User; +import de.symeda.sormas.backend.visit.Visit; public class CaseJoins extends QueryJoins { @@ -70,6 +72,9 @@ public class CaseJoins extends QueryJoins { private Join externalShareInfo; private Join followUpStatusChangeUser; + private Join visit; + private Join surveillanceReportJoin; + private PersonJoins personJoins; private SampleJoins sampleJoins; private EventParticipantJoins eventParticipantJoins; @@ -130,6 +135,10 @@ public Join getDistrict() { return getOrCreate(district, Case.DISTRICT, JoinType.LEFT, this::setDistrict); } + private void setDistrict(Join district) { + this.district = district; + } + public Join getCommunity() { return getOrCreate(community, Case.COMMUNITY, JoinType.LEFT, this::setCommunity); } @@ -138,10 +147,6 @@ private void setCommunity(Join community) { this.community = community; } - private void setDistrict(Join district) { - this.district = district; - } - public Join getFacility() { return getOrCreate(facility, Case.HEALTH_FACILITY, JoinType.LEFT, this::setFacility); } @@ -234,14 +239,14 @@ private void setHealthConditions(Join healthConditions) this.healthConditions = healthConditions; } - private void setEventParticipants(Join eventParticipants) { - this.eventParticipants = eventParticipants; - } - public Join getEventParticipants() { return getOrCreate(eventParticipants, Case.EVENT_PARTICIPANTS, JoinType.LEFT, this::setEventParticipants); } + private void setEventParticipants(Join eventParticipants) { + this.eventParticipants = eventParticipants; + } + public Join> getPersonAddresses() { return getPersonJoins().getAddresses(); } @@ -313,4 +318,20 @@ public EventParticipantJoins getEventParticipantJoins() { private void setEventParticipantJoins(EventParticipantJoins eventParticipantJoins) { this.eventParticipantJoins = eventParticipantJoins; } + + public Join getVisit() { + return getOrCreate(visit, Case.VISITS, JoinType.LEFT, this::setVisit); + } + + private void setVisit(Join visit) { + this.visit = visit; + } + + public Join getSurveillanceReportJoin() { + return getOrCreate(surveillanceReportJoin, Case.SURVEILLANCE_REPORTS, JoinType.LEFT, this::setSurveillanceReportJoin); + } + + private void setSurveillanceReportJoin(Join surveillanceReportJoin) { + this.surveillanceReportJoin = surveillanceReportJoin; + } } 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 fc092118376..df8ef4b53e4 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 @@ -180,7 +180,7 @@ @Stateless @LocalBean -public class CaseService extends AbstractCoreAdoService { +public class CaseService extends AbstractCoreAdoService { private static final Double SECONDS_30_DAYS = Long.valueOf(TimeUnit.DAYS.toSeconds(30L)).doubleValue(); @@ -934,7 +934,7 @@ public Predicate createCriteriaFilter(CaseCrite cb, from, ExternalShareInfo.CAZE, - (latestShareDate) -> createChangeDateFilter(cq, cb, from, joins, latestShareDate, true, true))); + (latestShareDate) -> createChangeDateFilter(cq, cb, joins, latestShareDate, true, true))); return filter; } @@ -1206,7 +1206,7 @@ private void deleteCaseLinks(Case caze) { @Override public Predicate createChangeDateFilter(CriteriaBuilder cb, From casePath, Timestamp date) { - return createChangeDateFilter(cb, casePath, date, false); + return createChangeDateFilter(cb, toJoins(casePath), date, false); } /** @@ -1217,38 +1217,26 @@ public Predicate createChangeDateFilter(CriteriaBuilder cb, From casePa * additional change dates filters for: sample, pathogenTests, patient and location * @return */ - public Predicate createChangeDateFilter(CriteriaBuilder cb, From casePath, Timestamp date, boolean includeExtendedChangeDateFilters) { + public Predicate createChangeDateFilter(CriteriaBuilder cb, CaseJoins joins, Timestamp date, boolean includeExtendedChangeDateFilters) { - return addChangeDates(new ChangeDateFilterBuilder(cb, date), casePath, includeExtendedChangeDateFilters).build(); - } - - private Predicate createChangeDateFilter( - CriteriaBuilder cb, - From casePath, - Timestamp date, - boolean includeExtendedChangeDateFilters, - String lastSynchronizedUuid) { - - return addChangeDates(new ChangeDateFilterBuilder(cb, date, casePath, lastSynchronizedUuid), casePath, includeExtendedChangeDateFilters) - .build(); + return addChangeDates(new ChangeDateFilterBuilder(cb, date), joins, includeExtendedChangeDateFilters).build(); } private Predicate createChangeDateFilter( CriteriaQuery cq, CriteriaBuilder cb, - From casePath, CaseJoins joins, Expression dateExpression, boolean includeExtendedChangeDateFilters, boolean includeRelevantVaccinations) { - ChangeDateFilterBuilder builder = addChangeDates(new ChangeDateFilterBuilder(cb, dateExpression), casePath, includeExtendedChangeDateFilters); + ChangeDateFilterBuilder builder = addChangeDates(new ChangeDateFilterBuilder(cb, dateExpression), joins, includeExtendedChangeDateFilters); if (includeRelevantVaccinations) { Join immunizationJoin = joins.getPersonJoins().getImmunization(); Join vaccinationsJoin = immunizationJoin.join(Immunization.VACCINATIONS, JoinType.LEFT); - builder.add(vaccinationsJoin.on(vaccinationService.getRelevantVaccinationPredicate(casePath, cq, cb, vaccinationsJoin))); + builder.add(vaccinationsJoin.on(vaccinationService.getRelevantVaccinationPredicate(joins.getRoot(), cq, cb, vaccinationsJoin))); // also consider the immunization of relevant vaccinations builder.add(vaccinationsJoin, Vaccination.IMMUNIZATION); @@ -1258,11 +1246,12 @@ private Predicate createChangeDateFilter( } @Override - protected > T addChangeDates(T builder, From caseFrom, boolean includeExtendedChangeDateFilters) { - Join hospitalization = caseFrom.join(Case.HOSPITALIZATION, JoinType.LEFT); - Join clinicalCourse = caseFrom.join(Case.CLINICAL_COURSE, JoinType.LEFT); + protected > T addChangeDates(T builder, CaseJoins joins, boolean includeExtendedChangeDateFilters) { + final From caseFrom = joins.getRoot(); + Join hospitalization = joins.getHospitalization(); + Join clinicalCourse = joins.getClinicalCourse(); - builder = super.addChangeDates(builder, caseFrom, includeExtendedChangeDateFilters).add(caseFrom, Case.SYMPTOMS) + builder = super.addChangeDates(builder, joins, includeExtendedChangeDateFilters).add(caseFrom, Case.SYMPTOMS) .add(hospitalization) .add(hospitalization, Hospitalization.PREVIOUS_HOSPITALIZATIONS) .add(caseFrom, Case.THERAPY) @@ -1273,13 +1262,13 @@ protected > T addChangeDates(T builder, From caseSampleJoin = caseFrom.join(Case.SAMPLES, JoinType.LEFT); - Join casePersonJoin = caseFrom.join(Case.PERSON, JoinType.LEFT); - Join caseVisitJoin = caseFrom.join(Case.VISITS, JoinType.LEFT); - Join caseSurveillanceReportJoin = caseFrom.join(Case.SURVEILLANCE_REPORTS, JoinType.LEFT); + Join caseSampleJoin = joins.getSamples(); + Join casePersonJoin = joins.getPerson(); + Join caseVisitJoin = joins.getVisit(); + Join caseSurveillanceReportJoin = joins.getSurveillanceReportJoin(); builder = builder.add(caseSampleJoin) .add(caseSampleJoin, Sample.PATHOGENTESTS) @@ -1298,6 +1287,11 @@ protected Predicate createUserFilterInternal(CriteriaBuilder cb, CriteriaQuery c return createUserFilter(new CaseQueryContext(cb, cq, from)); } + @Override + protected CaseJoins toJoins(From adoPath) { + return new CaseJoins(adoPath); + } + public Predicate createUserFilter(CaseQueryContext caseQueryContext) { return createUserFilter(caseQueryContext, null); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractCoreAdoService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractCoreAdoService.java index 6594374cc51..4933e129a35 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractCoreAdoService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractCoreAdoService.java @@ -40,7 +40,7 @@ import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb.FeatureConfigurationFacadeEjbLocal; import de.symeda.sormas.backend.util.IterableHelper; -public abstract class AbstractCoreAdoService extends AbstractDeletableAdoService { +public abstract class AbstractCoreAdoService> extends AbstractDeletableAdoService { private static final int ARCHIVE_BATCH_SIZE = 1000; @@ -93,8 +93,14 @@ public boolean isDeleted(String uuid) { return count > 0; } - protected > T addChangeDates(T builder, From adoPath, boolean includeExtendedChangeDateFilters) { - return builder.add(adoPath); + protected abstract J toJoins(From adoPath); + + private > T addChangeDates(T builder, From adoPath, boolean includeExtendedChangeDateFilters) { + return addChangeDates(builder, toJoins(adoPath), includeExtendedChangeDateFilters); + } + + protected > T addChangeDates(T builder, J joins, boolean includeExtendedChangeDateFilters) { + return builder.add(joins.getRoot()); } public Map calculateEndOfProcessingDate(List entityuuids) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractCoreFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractCoreFacadeEjb.java index bd81760c9b5..de6dc91c91d 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractCoreFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractCoreFacadeEjb.java @@ -52,7 +52,7 @@ import de.symeda.sormas.backend.user.UserService; import de.symeda.sormas.backend.util.Pseudonymizer; -public abstract class AbstractCoreFacadeEjb, CRITERIA extends BaseCriteria> +public abstract class AbstractCoreFacadeEjb>, CRITERIA extends BaseCriteria> extends AbstractBaseEjb implements CoreFacade { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/BaseAdoService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/BaseAdoService.java index cdb6edc1426..4b67232c96f 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/BaseAdoService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/BaseAdoService.java @@ -394,6 +394,10 @@ public Predicate createChangeDateFilter(CriteriaBuilder cb, From from, T return cb.greaterThan(from.get(AbstractDomainObject.CHANGE_DATE), date); } + public Predicate createChangeDateFilter(CriteriaBuilder cb, QueryJoins joins, Timestamp date) { + return cb.greaterThan(joins.getRoot().get(AbstractDomainObject.CHANGE_DATE), date); + } + public Predicate createChangeDateFilter(CriteriaBuilder cb, From from, Date date) { return createChangeDateFilter(cb, from, DateHelper.toTimestampUpper(date)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactJoins.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactJoins.java index 7e56a338f85..323e4790f5b 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactJoins.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactJoins.java @@ -223,7 +223,7 @@ public Join getVisitSymptoms() { } public Join getHealthConditions() { - return healthConditions; + return getOrCreate(healthConditions, Contact.HEALTH_CONDITIONS, JoinType.LEFT, this::setHealthConditions); } public void setHealthConditions(Join healthConditions) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java index d0d025927e7..f6072873539 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java @@ -137,7 +137,7 @@ @Stateless @LocalBean -public class ContactService extends AbstractCoreAdoService +public class ContactService extends AbstractCoreAdoService implements JurisdictionFlagsService { @EJB @@ -213,38 +213,45 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c @Override public Predicate createChangeDateFilter(CriteriaBuilder cb, From from, Date date) { - return createChangeDateFilter(cb, from, DateHelper.toTimestampUpper(date), null); + return createChangeDateFilter(cb, toJoins(from), DateHelper.toTimestampUpper(date), null); } @Override public Predicate createChangeDateFilter(CriteriaBuilder cb, From from, Timestamp date) { - return createChangeDateFilter(cb, from, DateHelper.toTimestampUpper(date), null); + return createChangeDateFilter(cb, toJoins(from), DateHelper.toTimestampUpper(date), null); } @Override public Predicate createChangeDateFilter(CriteriaBuilder cb, From from, Date date, String lastSynchronizedUuid) { - return createChangeDateFilter(cb, from, DateHelper.toTimestampUpper(date), null); + return createChangeDateFilter(cb, toJoins(from), DateHelper.toTimestampUpper(date), null); } - public Predicate createChangeDateFilter(CriteriaBuilder cb, From from, Timestamp date, String lastSynchronizedUuid) { - ChangeDateFilterBuilder changeDateFilterBuilder = new ChangeDateFilterBuilder(cb, date, from, lastSynchronizedUuid); - return addChangeDates(changeDateFilterBuilder, from, false).build(); + public Predicate createChangeDateFilter(CriteriaBuilder cb, ContactJoins joins, Timestamp date, String lastSynchronizedUuid) { + + ChangeDateFilterBuilder changeDateFilterBuilder = new ChangeDateFilterBuilder(cb, date, joins.getRoot(), lastSynchronizedUuid); + return addChangeDates(changeDateFilterBuilder, joins, false).build(); } @Override - protected > T addChangeDates(T builder, From contactFrom, boolean includeExtendedChangeDateFilters) { - Join healthCondition = contactFrom.join(Contact.HEALTH_CONDITIONS, JoinType.LEFT); - Join epiData = contactFrom.join(Contact.EPI_DATA, JoinType.LEFT); + protected ContactJoins toJoins(From adoPath) { + return new ContactJoins(adoPath); + } + + @Override + protected > T addChangeDates(T builder, ContactJoins joins, boolean includeExtendedChangeDateFilters) { + + Join healthCondition = joins.getHealthConditions(); + Join epiData = joins.getEpiData(); - builder = super.addChangeDates(builder, contactFrom, includeExtendedChangeDateFilters).add(healthCondition) - .add(contactFrom, Contact.SORMAS_TO_SORMAS_ORIGIN_INFO) - .add(contactFrom, Contact.SORMAS_TO_SORMAS_SHARES); + builder = super.addChangeDates(builder, joins, includeExtendedChangeDateFilters).add(healthCondition) + .add(joins.getRoot(), Contact.SORMAS_TO_SORMAS_ORIGIN_INFO) + .add(joins.getRoot(), Contact.SORMAS_TO_SORMAS_SHARES); builder = epiDataService.addChangeDates(builder, epiData); if (includeExtendedChangeDateFilters) { - Join contactSampleJoin = contactFrom.join(Contact.SAMPLES, JoinType.LEFT); - Join contactVisitJoin = contactFrom.join(Contact.VISITS, JoinType.LEFT); + Join contactSampleJoin = joins.getSamples(); + Join contactVisitJoin = joins.getVisits(); builder.add(contactSampleJoin).add(contactSampleJoin, Sample.PATHOGENTESTS).add(contactVisitJoin); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventJoins.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventJoins.java index ce079117f01..4a2c61817a5 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventJoins.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventJoins.java @@ -21,6 +21,7 @@ import javax.persistence.criteria.Join; import javax.persistence.criteria.JoinType; +import de.symeda.sormas.backend.action.Action; import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.common.QueryJoins; import de.symeda.sormas.backend.infrastructure.community.Community; @@ -39,6 +40,7 @@ public class EventJoins extends QueryJoins { private Join location; private From eventParticipants; private Join eventGroup; + private Join eventActions; private Join superordinateEvent; private LocationJoins locationJoins; @@ -133,6 +135,14 @@ private void setSuperordinateEvent(Join superordinateEvent) { this.superordinateEvent = superordinateEvent; } + public Join getEventActions() { + return getOrCreate(eventActions, Event.ACTIONS, JoinType.LEFT, this::setEventActions); + } + + private void setEventActions(Join eventActions) { + this.eventActions = eventActions; + } + public LocationJoins getLocationJoins() { return getOrCreate(locationJoins, () -> new LocationJoins(getLocation()), this::setLocationJoins); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java index 7af2c39fd05..ce30cc7e7fb 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java @@ -70,7 +70,7 @@ @Stateless @LocalBean -public class EventParticipantService extends AbstractCoreAdoService { +public class EventParticipantService extends AbstractCoreAdoService { @EJB private EventService eventService; @@ -273,6 +273,11 @@ protected Predicate createUserFilterInternal(CriteriaBuilder cb, CriteriaQuery c return createUserFilter(new EventParticipantQueryContext(cb, cq, from)); } + @Override + protected EventParticipantJoins toJoins(From adoPath) { + return new EventParticipantJoins(adoPath); + } + public Predicate createUserFilter(EventParticipantQueryContext eventParticipantQueryContext) { final EventUserFilterCriteria eventUserFilterCriteria = new EventUserFilterCriteria(); @@ -488,22 +493,23 @@ public List getByEventUuids(List eventUuids) { public Predicate createChangeDateFilter(CriteriaBuilder cb, From from, Timestamp date) { ChangeDateFilterBuilder changeDateFilterBuilder = new ChangeDateFilterBuilder(cb, date, from, null); - return addChangeDates(changeDateFilterBuilder, from, false).build(); - + return addChangeDates(changeDateFilterBuilder, toJoins(from), false).build(); } @Override protected > T addChangeDates( T builder, - From eventParticipantFrom, + EventParticipantJoins joins, boolean includeExtendedChangeDateFilters) { - builder = super.addChangeDates(builder, eventParticipantFrom, includeExtendedChangeDateFilters) + From eventParticipantFrom = joins.getRoot(); + + builder = super.addChangeDates(builder, joins, includeExtendedChangeDateFilters) .add(eventParticipantFrom, EventParticipant.SORMAS_TO_SORMAS_ORIGIN_INFO) .add(eventParticipantFrom, EventParticipant.SORMAS_TO_SORMAS_SHARES); if (includeExtendedChangeDateFilters) { - Join eventParticipantSampleJoin = eventParticipantFrom.join(EventParticipant.SAMPLES, JoinType.LEFT); + Join eventParticipantSampleJoin = joins.getSamples(); builder.add(eventParticipantSampleJoin).add(eventParticipantSampleJoin, Sample.PATHOGENTESTS); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java index 57a3f0c6867..02a0edf2ae3 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java @@ -105,7 +105,7 @@ @Stateless @LocalBean -public class EventService extends AbstractCoreAdoService { +public class EventService extends AbstractCoreAdoService { @EJB private EventParticipantService eventParticipantService; @@ -393,6 +393,11 @@ protected Predicate createUserFilterInternal(CriteriaBuilder cb, CriteriaQuery c return createUserFilter(new EventQueryContext(cb, cq, from)); } + @Override + protected EventJoins toJoins(From adoPath) { + return new EventJoins(adoPath); + } + public Predicate createUserFilter(EventQueryContext queryContext) { return createUserFilter(queryContext, null); } @@ -519,34 +524,28 @@ public Predicate createCaseAndEventParticipantFilter(EventQueryContext eventQuer @Override public Predicate createChangeDateFilter(CriteriaBuilder cb, From eventPath, Timestamp date) { - return addChangeDates(new ChangeDateFilterBuilder(cb, date), eventPath, false).build(); + return addChangeDates(new ChangeDateFilterBuilder(cb, date), toJoins(eventPath), false).build(); } - private Predicate createChangeDateFilter(CriteriaBuilder cb, From eventPath, Timestamp date, String lastSynchronizedUuid) { - ChangeDateFilterBuilder changeDateFilterBuilder = lastSynchronizedUuid == null - ? new ChangeDateFilterBuilder(cb, date) - : new ChangeDateFilterBuilder(cb, date, eventPath, lastSynchronizedUuid); - - return addChangeDates(changeDateFilterBuilder, eventPath, false).build(); - } - - public Predicate createChangeDateFilter(CriteriaBuilder cb, From eventPath, Expression dateExpression) { - return addChangeDates(new ChangeDateFilterBuilder(cb, dateExpression), eventPath, false).build(); + public Predicate createChangeDateFilter(CriteriaBuilder cb, EventJoins joins, Expression dateExpression) { + return addChangeDates(new ChangeDateFilterBuilder(cb, dateExpression), joins, false).build(); } @Override - protected > T addChangeDates(T builder, From eventFrom, boolean includeExtendedChangeDateFilters) { - Join eventActionJoin = eventFrom.join(Event.ACTIONS, JoinType.LEFT); - Join eventParticipantJoin = eventFrom.join(Event.EVENT_PERSONS, JoinType.LEFT); - Join eventParticipantSampleJoin = eventParticipantJoin.join(EventParticipant.SAMPLES, JoinType.LEFT); + protected > T addChangeDates(T builder, EventJoins joins, boolean includeExtendedChangeDateFilters) { + + final From eventFrom = joins.getRoot(); + final Join eventActionJoin = joins.getEventActions(); + final From eventParticipants = joins.getEventParticipants(); + final Join eventParticipantSampleJoin = joins.getEventParticipantJoins().getSamples(); - builder = super.addChangeDates(builder, eventFrom, includeExtendedChangeDateFilters).add(eventFrom, Event.EVENT_LOCATION); + builder = super.addChangeDates(builder, joins, includeExtendedChangeDateFilters).add(eventFrom, Event.EVENT_LOCATION); if (includeExtendedChangeDateFilters) { builder.add(eventFrom, Event.SORMAS_TO_SORMAS_ORIGIN_INFO) .add(eventFrom, Event.SORMAS_TO_SORMAS_SHARES) .add(eventActionJoin) - .add(eventParticipantJoin) + .add(eventParticipants) .add(eventParticipantSampleJoin); } @@ -838,7 +837,7 @@ public Predicate buildCriteriaFilter(EventCriteria eventCriteria, EventQueryCont cb, from, ExternalShareInfo.EVENT, - (latestShareDate) -> createChangeDateFilter(cb, from, latestShareDate))); + (latestShareDate) -> createChangeDateFilter(cb, joins, latestShareDate))); return filter; } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationJoins.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationJoins.java index c732acbd31e..6d0dba41061 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationJoins.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationJoins.java @@ -22,10 +22,12 @@ import de.symeda.sormas.backend.immunization.entity.Immunization; import de.symeda.sormas.backend.sormastosormas.share.outgoing.SormasToSormasShareInfo; import de.symeda.sormas.backend.user.User; +import de.symeda.sormas.backend.vaccination.Vaccination; public class ImmunizationJoins extends BaseImmunizationJoins { private Join reportingUser; + private Join vaccinations; private Join sormasToSormasShareInfo; @@ -48,4 +50,12 @@ public Join getSormasToSormasShareInfo() private void setSormasToSormasShareInfo(Join sormasToSormasShareInfo) { this.sormasToSormasShareInfo = sormasToSormasShareInfo; } + + public Join getVaccinations() { + return getOrCreate(vaccinations, Immunization.VACCINATIONS, JoinType.LEFT, this::setVaccinations); + } + + private void setVaccinations(Join vaccinations) { + this.vaccinations = vaccinations; + } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java index b2a57f2ebcb..f546f66d177 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java @@ -78,7 +78,7 @@ @Stateless @LocalBean -public class ImmunizationService extends AbstractCoreAdoService { +public class ImmunizationService extends AbstractCoreAdoService { @EJB private PersonService personService; @@ -195,30 +195,34 @@ public Predicate createDefaultFilter(CriteriaBuilder cb, From r @Override public Predicate createChangeDateFilter(CriteriaBuilder cb, From immunization, Timestamp date) { - return createChangeDateFilter(cb, immunization, date, null); + return createChangeDateFilter(cb, toJoins(immunization), date, null); } @Override protected > T addChangeDates( T builder, - From immunizationFrom, + ImmunizationJoins joins, boolean includeExtendedChangeDateFilters) { - Join vaccinations = immunizationFrom.join(Immunization.VACCINATIONS, JoinType.LEFT); + From immunizationFrom = joins.getRoot(); - builder = super.addChangeDates(builder, immunizationFrom, includeExtendedChangeDateFilters).add(vaccinations) + Join vaccinations = joins.getVaccinations(); + + builder = super.addChangeDates(builder, joins, includeExtendedChangeDateFilters).add(vaccinations) .add(immunizationFrom, Immunization.SORMAS_TO_SORMAS_ORIGIN_INFO) .add(immunizationFrom, Immunization.SORMAS_TO_SORMAS_SHARES); return builder; } - private Predicate createChangeDateFilter(CriteriaBuilder cb, From immunization, Timestamp date, String lastSynchronizedUuid) { + private Predicate createChangeDateFilter(CriteriaBuilder cb, ImmunizationJoins joins, Timestamp date, String lastSynchronizedUuid) { + + From immunization = joins.getRoot(); ChangeDateFilterBuilder changeDateFilterBuilder = lastSynchronizedUuid == null ? new ChangeDateFilterBuilder(cb, date) : new ChangeDateFilterBuilder(cb, date, immunization, lastSynchronizedUuid); - return addChangeDates(changeDateFilterBuilder, immunization, false).build(); + return addChangeDates(changeDateFilterBuilder, joins, false).build(); } @Override @@ -245,6 +249,11 @@ public boolean isArchived(String uuid) { return count > 0; } + @Override + protected ImmunizationJoins toJoins(From adoPath) { + return new ImmunizationJoins(adoPath); + } + public List getArchivedUuidsSince(Date since) { CriteriaBuilder cb = em.getCriteriaBuilder(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/AbstractSormasToSormasInterface.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/AbstractSormasToSormasInterface.java index b1a378a0a8b..bcf194ab3b7 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/AbstractSormasToSormasInterface.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/AbstractSormasToSormasInterface.java @@ -83,6 +83,7 @@ import de.symeda.sormas.backend.common.AbstractCoreAdoService; import de.symeda.sormas.backend.common.ConfigFacadeEjb; import de.symeda.sormas.backend.common.CoreAdo; +import de.symeda.sormas.backend.common.QueryJoins; import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.contact.ContactService; import de.symeda.sormas.backend.event.Event; @@ -594,7 +595,7 @@ private ValidationErrorGroup buildEntityValidationGroupName(String uuid) { return buildValidationGroupName(entityCaptionTag, uuid); } - protected abstract AbstractCoreAdoService getEntityService(); + protected abstract AbstractCoreAdoService getEntityService(); protected abstract Class getShareDataClass(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/caze/SormasToSormasCaseFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/caze/SormasToSormasCaseFacadeEjb.java index be3eaf28410..b8a1b51cc85 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/caze/SormasToSormasCaseFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/caze/SormasToSormasCaseFacadeEjb.java @@ -56,6 +56,7 @@ import de.symeda.sormas.api.utils.AccessDeniedException; import de.symeda.sormas.api.utils.DataHelper; import de.symeda.sormas.backend.caze.Case; +import de.symeda.sormas.backend.caze.CaseJoins; import de.symeda.sormas.backend.caze.CaseService; import de.symeda.sormas.backend.common.AbstractCoreAdoService; import de.symeda.sormas.backend.contact.Contact; @@ -123,7 +124,7 @@ public void share(List entityUuids, @Valid SormasToSormasOptionsDto opti } @Override - protected AbstractCoreAdoService getEntityService() { + protected AbstractCoreAdoService getEntityService() { return caseService; } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/contact/SormasToSormasContactFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/contact/SormasToSormasContactFacadeEjb.java index fd07723acbe..6d72ff338a1 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/contact/SormasToSormasContactFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/contact/SormasToSormasContactFacadeEjb.java @@ -54,6 +54,7 @@ import de.symeda.sormas.backend.caze.CaseFacadeEjb.CaseFacadeEjbLocal; import de.symeda.sormas.backend.common.AbstractCoreAdoService; import de.symeda.sormas.backend.contact.Contact; +import de.symeda.sormas.backend.contact.ContactJoins; import de.symeda.sormas.backend.contact.ContactService; import de.symeda.sormas.backend.immunization.ImmunizationService; import de.symeda.sormas.backend.sample.SampleService; @@ -120,7 +121,7 @@ public void share(List entityUuids, SormasToSormasOptionsDto options) th } @Override - protected AbstractCoreAdoService getEntityService() { + protected AbstractCoreAdoService getEntityService() { return contactService; } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/event/SormasToSormasEventFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/event/SormasToSormasEventFacadeEjb.java index fb8572fa262..37e99d61114 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/event/SormasToSormasEventFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/event/SormasToSormasEventFacadeEjb.java @@ -50,6 +50,7 @@ import de.symeda.sormas.api.utils.AccessDeniedException; import de.symeda.sormas.backend.common.AbstractCoreAdoService; import de.symeda.sormas.backend.event.Event; +import de.symeda.sormas.backend.event.EventJoins; import de.symeda.sormas.backend.event.EventParticipant; import de.symeda.sormas.backend.event.EventParticipantService; import de.symeda.sormas.backend.event.EventService; @@ -213,7 +214,7 @@ protected List getOrCreateShareInfos(Event event, Sorma } @Override - protected AbstractCoreAdoService getEntityService() { + protected AbstractCoreAdoService getEntityService() { return eventService; } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/BaseTravelEntryService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/BaseTravelEntryService.java index 031c70940ee..bc40ad2be28 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/BaseTravelEntryService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/BaseTravelEntryService.java @@ -11,12 +11,13 @@ import de.symeda.sormas.backend.common.CriteriaBuilderHelper; import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.travelentry.TravelEntry; +import de.symeda.sormas.backend.travelentry.TravelEntryJoins; import de.symeda.sormas.backend.travelentry.TravelEntryJurisdictionPredicateValidator; import de.symeda.sormas.backend.travelentry.TravelEntryQueryContext; import de.symeda.sormas.backend.user.User; import de.symeda.sormas.backend.user.UserService; -public abstract class BaseTravelEntryService extends AbstractCoreAdoService { +public abstract class BaseTravelEntryService extends AbstractCoreAdoService { @EJB protected UserService userService; @@ -26,14 +27,14 @@ protected BaseTravelEntryService() { } @Override - public Predicate inJurisdictionOrOwned(CriteriaBuilder cb, CriteriaQuery query, From from) { + public Predicate inJurisdictionOrOwned(CriteriaBuilder cb, CriteriaQuery query, From from) { return inJurisdictionOrOwned(new TravelEntryQueryContext(cb, query, from)); } public Predicate inJurisdictionOrOwned(TravelEntryQueryContext qc) { return inJurisdictionOrOwned(qc, userService.getCurrentUser()); } - + public Predicate inJurisdictionOrOwned(TravelEntryQueryContext qc, User user) { return TravelEntryJurisdictionPredicateValidator.of(qc, user).inJurisdictionOrOwned(); } @@ -61,6 +62,11 @@ public Predicate createUserFilter(TravelEntryQueryContext qc) { return filter; } + @Override + protected TravelEntryJoins toJoins(From adoPath) { + return new TravelEntryJoins(adoPath); + } + @Override @SuppressWarnings("rawtypes") protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { @@ -74,11 +80,8 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c } @Override - protected > T addChangeDates( - T builder, - From travelEntryFrom, - boolean includeExtendedChangeDateFilters) { + protected > T addChangeDates(T builder, TravelEntryJoins joins, boolean includeExtendedChangeDateFilters) { - return super.addChangeDates(builder, travelEntryFrom, includeExtendedChangeDateFilters); + return super.addChangeDates(builder, joins, includeExtendedChangeDateFilters); } } From 5d957d7653ddf7aeaecae77e57e38374b22291d5 Mon Sep 17 00:00:00 2001 From: Razvan Date: Fri, 23 Dec 2022 17:40:49 +0200 Subject: [PATCH 041/166] #10418SampleTimeStampTest : created test --- .../pages/application/cases/EditCasePage.java | 2 ++ .../web/application/cases/EditCaseSteps.java | 13 ++++++++++++ .../features/sanity/web/Case.feature | 20 ++++++++++++++++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/EditCasePage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/EditCasePage.java index f41f9b2b693..a3247589d1b 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/EditCasePage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/EditCasePage.java @@ -239,6 +239,8 @@ public class EditCasePage { public static final By UPLOAD_DOCUMENT_CHECKBOX = By.xpath("//label[text()='Also upload the generated document to this entity']"); public static final By POPUPS_INPUTS = By.cssSelector(".popupContent input"); + public static final By QUARANTINE_ORDER_POPUP_SAMPLE_FIELD = + By.xpath("//span[text()='Sample']//following::input[1]"); public static final By VACCINATION_STATUS_INPUT = By.cssSelector("#vaccinationStatus input"); public static final By GENERATED_DOCUMENT_NAME = By.xpath( 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 ca9a308ee54..9a2b3fdf4e7 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 @@ -416,6 +416,19 @@ public EditCaseSteps( webDriverHelpers.selectFromCombobox(QUARANTINE_ORDER_COMBOBOX, name); webDriverHelpers.waitUntilANumberOfElementsAreVisibleAndClickable(POPUPS_INPUTS, 5); }); + When( + "Sample name timestamp is correct in Create Quarantine Order form from Edit Case directory", + () -> { + String sampleFieldValue = + webDriverHelpers.getValueFromWebElement(QUARANTINE_ORDER_POPUP_SAMPLE_FIELD); + String sampleDate = + CreateNewSampleSteps.sample + .getDateOfCollection() + .format(DateTimeFormatter.ofPattern("M/dd/yyyy")); + Assert.assertTrue( + sampleFieldValue.startsWith(sampleDate), + "Sample field date doesn't start with " + sampleDate); + }); When( "I select {string} Quarantine Order in Create Quarantine Order form in Case directory", (String name) -> { 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 643709c17f9..f1343d9b7ed 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 @@ -2082,4 +2082,22 @@ Feature: Case end to end tests And I check if created case is available in API And API: I check that POST call status code is 200 Then I filter with first Case ID - And I check that number of displayed cases results is 1 \ No newline at end of file + And I check that number of displayed cases results is 1 + + @env_main @#10418 + Scenario: Verify sample timestamp pattern from Quarantine Order popup + Given API: I create a new person + And API: I check that POST call body is "OK" + And API: I check that POST call status code is 200 + Given API: I create a new case + Then API: I check that POST call body is "OK" + 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 + Then I click on New Sample + Then I create a new Sample with positive test result with Guinea Worm as disease + And I confirm popup window + Then I navigate to the last created case via the url + And I click on Create button in Document Templates box in Edit Case directory + Then I select "ExampleDocumentTemplateCases.docx" Quarantine Order in Create Quarantine Order form in Edit Case directory + And Sample name timestamp is correct in Create Quarantine Order form from Edit Case directory From b8ea9f207b1b29026d3b161035d59525d2eba0bc Mon Sep 17 00:00:00 2001 From: Bal Andrei Date: Fri, 23 Dec 2022 18:08:18 +0200 Subject: [PATCH 042/166] #9742 Display errors as list --- .../symeda/sormas/ui/utils/CommitDiscardWrapperComponent.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CommitDiscardWrapperComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CommitDiscardWrapperComponent.java index 285a610b7ab..efbbf94e014 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CommitDiscardWrapperComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CommitDiscardWrapperComponent.java @@ -619,10 +619,12 @@ public boolean commitAndHandle() { } htmlMsg.append(""); } else if (firstCause != null) { + htmlMsg.append("
    "); String info = findHtmlMessage(firstCause); boolean validInfo = nonNull(info) && !info.isEmpty() && !info.equalsIgnoreCase("null"); if (validInfo) { - htmlMsg.append(info); + htmlMsg.append("
  • ").append(info).append("
  • "); + htmlMsg.append("
"); } String additionalInfo = findHtmlMessageDetails(firstCause); if (nonNull(additionalInfo) && !additionalInfo.isEmpty()) { From 6ceb395e5c30602c95309587685230c32a369e0c Mon Sep 17 00:00:00 2001 From: popadriangeo Date: Tue, 27 Dec 2022 17:37:11 +0200 Subject: [PATCH 043/166] # 10421 added Scenario: Validate newly created User Role cannot be deleted if assigned towards an user --- .../web/application/users/UserRolesSteps.java | 32 +++++++++++++++++++ .../features/sanity/web/User.feature | 22 +++++++++++++ 2 files changed, 54 insertions(+) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/users/UserRolesSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/users/UserRolesSteps.java index d3d9650f6cf..ce88b5ff104 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/users/UserRolesSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/users/UserRolesSteps.java @@ -228,6 +228,38 @@ public UserRolesSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { } }); + And( + "^I verify that the \"([^\"]*)\" user role exist and delete it$", + (String userRole) -> { + webDriverHelpers.waitUntilIdentifiedElementIsPresent(USER_RIGHTS_INPUT); + webDriverHelpers.scrollInTable(12); + webDriverHelpers.isElementVisibleWithTimeout(getUserRoleCaptionByText("TestNatUser"), 5); + webDriverHelpers.doubleClickOnWebElementBySelector(getUserRoleCaptionByText(userRole)); + webDriverHelpers.scrollToElement(DELETE_USER_ROLE_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(DELETE_USER_ROLE_BUTTON); + webDriverHelpers.waitUntilIdentifiedElementIsPresent(DELETE_CONFIRMATION_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(DELETE_CONFIRMATION_BUTTON); + }); + + And( + "^I check if the \"([^\"]*)\" user role cannot be deleted while assigned$", + (String userRole) -> { + webDriverHelpers.waitUntilIdentifiedElementIsPresent(USER_RIGHTS_INPUT); + webDriverHelpers.scrollInTable(12); + + if (webDriverHelpers.isElementVisibleWithTimeout( + getUserRoleCaptionByText("TestNatUser"), 5)) { + webDriverHelpers.doubleClickOnWebElementBySelector(getUserRoleCaptionByText(userRole)); + webDriverHelpers.scrollToElement(DELETE_USER_ROLE_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(DELETE_USER_ROLE_BUTTON); + webDriverHelpers.waitUntilIdentifiedElementIsPresent(DELETE_CONFIRMATION_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(DELETE_CONFIRMATION_BUTTON); + webDriverHelpers.waitUntilIdentifiedElementIsVisibleAndClickable( + CANNOT_DELETE_USER_ROLE_POPUP); + webDriverHelpers.clickOnWebElementBySelector(CANNOT_DELETE_USER_ROLE_POPUP_OKAY_BUTTON); + } + }); + And( "I click on the Export User Roles Button and verify User role file is downloaded and contains data in the User Role Page", () -> { diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/User.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/User.feature index 9a62b8da3e4..c7b5206cffb 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/User.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/User.feature @@ -358,3 +358,25 @@ Feature: Create user And I click on the Users from navbar And I click on User roles tab from User Management Page And I click on the Export User Roles Button and verify User role file is downloaded and contains data in the User Role Page + + @#10421 @env_main + Scenario: Validate newly created User Role cannot be deleted if assigned towards an user + Given I log in as a Admin User + And I click on the Users from navbar + And I check if there is any user with the "TestNatUser" role and change his role + And I click on User roles tab from User Management Page + And I check if the "TestNatUser" user role exist and delete it + And I click on New user role button on User Roles Page + And I choose "National User" as the user role template + And I fill caption input as "TestNatUser" on Create New User Role form + And I click SAVE button on User Role Page + And I back to the User role list + And I click on User Management tab from User Roles Page + And I click on the NEW USER button + And I create new "TestNatUser" with english language for test + And I click on User roles tab from User Management Page + And I check if the "TestNatUser" user role cannot be deleted while assigned + And I click on the Users from navbar + And I check if there is any user with the "TestNatUser" role and change his role + And I click on User roles tab from User Management Page + And I verify that the "TestNatUser" user role exist and delete it From 73de9e4e944833bd3977e942c49c6629b714f46c Mon Sep 17 00:00:00 2001 From: popadriangeo Date: Thu, 29 Dec 2022 14:10:29 +0200 Subject: [PATCH 044/166] #10421-fixed link to ticket --- .../src/test/resources/features/sanity/web/Task.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Task.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Task.feature index fc4f22b5447..5b5b9259f67 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Task.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Task.feature @@ -223,7 +223,7 @@ Feature: Tasks functionalities And I save Export Configuration for Custom Task Export And I delete last created custom task export config - @3384 @env_main + @8561 @env_main Scenario: Verify that Task assignee cannot be left empty via bulk edit mode Given I log in as a Admin User And I click on the Tasks button from navbar From 16daee09ad8c9123ebefc8a68b226a77d4ac77ce Mon Sep 17 00:00:00 2001 From: popadriangeo Date: Fri, 30 Dec 2022 11:21:53 +0200 Subject: [PATCH 045/166] #10421 - wait for element before attempting click action --- .../steps/web/application/tasks/TaskManagementSteps.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/tasks/TaskManagementSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/tasks/TaskManagementSteps.java index fe61e7f8bca..ab7259ff2b6 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/tasks/TaskManagementSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/tasks/TaskManagementSteps.java @@ -18,6 +18,7 @@ package org.sormas.e2etests.steps.web.application.tasks; +import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.LEAVE_BULK_EDIT_MODE; import static org.sormas.e2etests.pages.application.cases.CaseDirectoryPage.TOTAL_CASES_COUNTER; import static org.sormas.e2etests.pages.application.contacts.EditContactPage.NOTIFICATION_MESSAGE_POPUP; import static org.sormas.e2etests.pages.application.contacts.EditContactPage.POPUP_YES_BUTTON; @@ -256,7 +257,9 @@ public TaskManagementSteps( When( "^I select first (\\d+) results in grid in Task Directory$", (Integer number) -> { - webDriverHelpers.waitForPageLoadingSpinnerToDisappear(40); + webDriverHelpers.waitForPageLoaded(); + webDriverHelpers.waitUntilIdentifiedElementIsVisibleAndClickable( + LEAVE_BULK_EDIT_MODE, 50); for (int i = 2; i <= number + 1; i++) { webDriverHelpers.waitUntilElementIsVisibleAndClickable( getCheckboxByIndex(String.valueOf(i))); From 9b000a2bcfd500cc4001d8ace27766c5d0d71bf4 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Mon, 2 Jan 2023 11:16:25 +0100 Subject: [PATCH 046/166] fixes --- .../web/application/mSers/CreateNewAggregateReportSteps.java | 1 + 1 file changed, 1 insertion(+) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/mSers/CreateNewAggregateReportSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/mSers/CreateNewAggregateReportSteps.java index aaacda7541a..1296e831060 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/mSers/CreateNewAggregateReportSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/mSers/CreateNewAggregateReportSteps.java @@ -1095,6 +1095,7 @@ private void fillYear(String year) { } private void fillEpiWeek(String epiWeek) { + webDriverHelpers.clearComboboxInput(EPI_WEEK_INPUT_POPUP); webDriverHelpers.selectFromCombobox(EPI_WEEK_COMBOBOX_POPUP, epiWeek); } From 9471b6d2b262897934c56b7acbe021b528169dbf Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Mon, 2 Jan 2023 12:28:35 +0100 Subject: [PATCH 047/166] fixes --- .../e2etests/pages/application/mSers/MSersDirectoryPage.java | 3 ++- .../steps/web/application/mSers/MSersDirectorySteps.java | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/mSers/MSersDirectoryPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/mSers/MSersDirectoryPage.java index cfd96d07bf6..35cc950db62 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/mSers/MSersDirectoryPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/mSers/MSersDirectoryPage.java @@ -16,7 +16,8 @@ public class MSersDirectoryPage { public static final By DISPLAY_ONLY_DUPLICATE_REPORTS_CHECKBOX = By.xpath("//label[text()=\"Display only duplicate reports\"]"); public static final By DELETE_ICON = By.xpath("(//div[@class=\"component-wrap\"]//div)[1]"); - public static final By EDIT_ICON = By.xpath("(//div[@class=\"component-wrap\"]//div)[1]"); + public static final By THIRD_ROW_EDIT_ICON = + By.xpath("(//div[@class=\"component-wrap\"]//div)[3]"); public static final By DISEASE_COMBOBOX = By.cssSelector("#disease div"); public static final By POINT_OF_ENTRY_COMBOBOX = By.cssSelector("#pointOfEntry div"); public static final By FACILITY_COMBOBOX = By.cssSelector("#healthFacility div"); diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/mSers/MSersDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/mSers/MSersDirectorySteps.java index 17cbb650eb3..15fc95cbd1c 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/mSers/MSersDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/mSers/MSersDirectorySteps.java @@ -10,7 +10,6 @@ import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.DISEASE_COMBOBOX; import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.DISPLAY_ONLY_DUPLICATE_REPORTS_CHECKBOX; import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.DISTRICT_COMBOBOX; -import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.EDIT_ICON; import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.EPI_WEEK_FROM_COMOBOX; import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.EPI_WEEK_TO_COMOBOX; import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.FACILITY_COMBOBOX; @@ -23,6 +22,7 @@ import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.REPORT_DATA_BUTTON; import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.RESULT_IN_GRID; import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.SHOW_ROWS_FOR_DISEASES_LABEL; +import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.THIRD_ROW_EDIT_ICON; import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.YEAR_FROM_COMOBOX; import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.YEAR_FROM_INPUT; import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.YEAR_TO_COMOBOX; @@ -147,7 +147,7 @@ public MSersDirectorySteps( webDriverHelpers.isElementVisibleWithTimeout(DELETE_ICON, 5), "Delete icon is not visible"); softly.assertTrue( - webDriverHelpers.isElementVisibleWithTimeout(EDIT_ICON, 5), + webDriverHelpers.isElementVisibleWithTimeout(THIRD_ROW_EDIT_ICON, 5), "Edit icon is not visible"); softly.assertAll(); }); From a1ab95a3ca81e2f77c86d424019cf46f7bc2e28f Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Mon, 2 Jan 2023 14:32:53 +0100 Subject: [PATCH 048/166] fixes --- .../pages/application/tasks/TaskManagementPage.java | 4 ++++ .../web/application/tasks/TaskManagementSteps.java | 10 ++++++++++ .../test/resources/features/sanity/web/Task.feature | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/tasks/TaskManagementPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/tasks/TaskManagementPage.java index 7d757b1ec6d..f1fce174b99 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/tasks/TaskManagementPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/tasks/TaskManagementPage.java @@ -77,4 +77,8 @@ public static By getCustomExportByID(String id) { return By.xpath( String.format("//div[@class='popupContent']//div[contains(@id, '%s-download')]", id)); } + + public static By getEditTaskButtonByNumber(Integer number) { + return By.xpath(String.format("//table/tbody/tr[%x]/td[1]", number)); + } } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/tasks/TaskManagementSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/tasks/TaskManagementSteps.java index fe61e7f8bca..8a26b1fedc1 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/tasks/TaskManagementSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/tasks/TaskManagementSteps.java @@ -56,6 +56,7 @@ import org.sormas.e2etests.entities.pojo.web.Task; import org.sormas.e2etests.helpers.AssertHelpers; import org.sormas.e2etests.helpers.WebDriverHelpers; +import org.sormas.e2etests.pages.application.tasks.TaskManagementPage; import org.sormas.e2etests.state.ApiState; import org.sormas.e2etests.steps.BaseSteps; import org.sormas.e2etests.steps.web.application.cases.EditCaseSteps; @@ -109,6 +110,7 @@ public TaskManagementSteps( webDriverHelpers.fillInWebElement(ASSIGNED_USER_FILTER_INPUT, assignedUser); webDriverHelpers.clickOnWebElementBySelector(APPLY_FILTER); webDriverHelpers.waitUntilIdentifiedElementIsVisibleAndClickable(lastTaskEditButton, 40); + TimeUnit.SECONDS.sleep(3); webDriverHelpers.clickElementSeveralTimesUntilNextElementIsDisplayed( lastTaskEditButton, TASK_STATUS_OPTIONS, 6); }); @@ -583,6 +585,14 @@ public TaskManagementSteps( Assert.assertFalse( webDriverHelpers.isElementVisibleWithTimeout(getCustomExportByID(export_id), 1)); }); + + And( + "I click on edit task icon of the {int} displayed task on Task Directory page", + (Integer taskNumber) -> { + webDriverHelpers.clickOnWebElementBySelector( + TaskManagementPage.getEditTaskButtonByNumber(taskNumber)); + webDriverHelpers.waitForPageLoadingSpinnerToDisappear(30); + }); } public Task parseDetailedTaskExport(String fileName) { diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Task.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Task.feature index fc4f22b5447..bb51db50054 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Task.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Task.feature @@ -155,7 +155,7 @@ Feature: Tasks functionalities And I select "Contact OFFICER" user from Observed by combobox in new Task form And I delete "Contact OFFICER" user from Observed by in new Task form And I click on Save button in New Task form - When I open last created task from Tasks Directory + And I click on edit task icon of the 1 displayed task on Task Directory page Then I check that National CLINICIAN is visible in Observed By on Edit Task Page And I check that Surveillance SUPERVISOR is visible in Observed By on Edit Task Page And I check that Contact OFFICER is not visible in Observed By on Edit Task Page From afe9c39d279fefd4f238d01bc37e0a7ed945bb64 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Mon, 2 Jan 2023 16:42:32 +0100 Subject: [PATCH 049/166] fixes --- .../pages/application/configuration/CountriesTabPage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java index 4113ad63839..5f87cfe9a22 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java @@ -37,7 +37,7 @@ public class CountriesTabPage { public static final By COUNTRY_GRID_RESULTS_ROWS = By.cssSelector("[role=rowgroup] tr a"); public static final By NUMBER_OF_COUNTRIES = By.xpath( - "//div[@class='v-label v-widget v-label-undef-w bold v-label-bold vspace-top-none v-label-vspace-top-none align-right v-label-align-right']"); + "//div[@class='v-label v-widget bold v-label-bold vspace-top-none v-label-vspace-top-none align-right v-label-align-right v-label-undef-w']"); public static final By COUNTRIES_TABLE_DATA = By.tagName("td"); public static final By COUNTRIES_TABLE_ROW = By.cssSelector("div.v-grid-tablewrapper tbody tr"); public static final By COUNTRIES_NAME_TABLE_ROW = From 3995820226311a9def0bf003f3333a673b663005 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Mon, 2 Jan 2023 16:44:56 +0100 Subject: [PATCH 050/166] revert --- .../pages/application/configuration/CountriesTabPage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java index 5f87cfe9a22..4113ad63839 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java @@ -37,7 +37,7 @@ public class CountriesTabPage { public static final By COUNTRY_GRID_RESULTS_ROWS = By.cssSelector("[role=rowgroup] tr a"); public static final By NUMBER_OF_COUNTRIES = By.xpath( - "//div[@class='v-label v-widget bold v-label-bold vspace-top-none v-label-vspace-top-none align-right v-label-align-right v-label-undef-w']"); + "//div[@class='v-label v-widget v-label-undef-w bold v-label-bold vspace-top-none v-label-vspace-top-none align-right v-label-align-right']"); public static final By COUNTRIES_TABLE_DATA = By.tagName("td"); public static final By COUNTRIES_TABLE_ROW = By.cssSelector("div.v-grid-tablewrapper tbody tr"); public static final By COUNTRIES_NAME_TABLE_ROW = From c043682caed4b7bcefd0b65977203019bdfb1d96 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Mon, 2 Jan 2023 16:50:02 +0100 Subject: [PATCH 051/166] fixes --- .../pages/application/configuration/CountriesTabPage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java index 4113ad63839..89bbe4adaa3 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java @@ -37,7 +37,7 @@ public class CountriesTabPage { public static final By COUNTRY_GRID_RESULTS_ROWS = By.cssSelector("[role=rowgroup] tr a"); public static final By NUMBER_OF_COUNTRIES = By.xpath( - "//div[@class='v-label v-widget v-label-undef-w bold v-label-bold vspace-top-none v-label-vspace-top-none align-right v-label-align-right']"); + "//div[@class='v-label v-widget bold v-label-bold vspace-top-none v-label-vspace-top-none align-right v-label-align-right v-label-undef-w']"); public static final By COUNTRIES_TABLE_DATA = By.tagName("td"); public static final By COUNTRIES_TABLE_ROW = By.cssSelector("div.v-grid-tablewrapper tbody tr"); public static final By COUNTRIES_NAME_TABLE_ROW = From c59190b3bd80e870c69f94cf2b09c63b729a0dd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=A9=20Strysewske?= Date: Tue, 3 Jan 2023 10:55:50 +0100 Subject: [PATCH 052/166] #9360 - Refactoring, make point of entry field pseudonymized --- .../porthealthinfo/PortHealthInfoDto.java | 8 +-- .../PortHealthInfoFacadeEjb.java | 26 +-------- .../porthealthinfo/PortHealthInfoService.java | 23 ++++++++ .../pointofentry/PointOfEntryFacadeEjb.java | 24 +------- .../pointofentry/PointOfEntryService.java | 56 +++++++++++++------ .../porthealthinfo/PortHealthInfoForm.java | 16 +++++- 6 files changed, 83 insertions(+), 70 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/caze/porthealthinfo/PortHealthInfoDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/caze/porthealthinfo/PortHealthInfoDto.java index 7220bdb6ee6..d87d0fef861 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/caze/porthealthinfo/PortHealthInfoDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/caze/porthealthinfo/PortHealthInfoDto.java @@ -1,14 +1,14 @@ package de.symeda.sormas.api.caze.porthealthinfo; -import de.symeda.sormas.api.feature.FeatureType; -import de.symeda.sormas.api.utils.DependingOnFeatureType; import java.util.Date; import javax.validation.constraints.Size; import de.symeda.sormas.api.EntityDto; +import de.symeda.sormas.api.feature.FeatureType; import de.symeda.sormas.api.i18n.Validations; import de.symeda.sormas.api.utils.DataHelper; +import de.symeda.sormas.api.utils.DependingOnFeatureType; import de.symeda.sormas.api.utils.FieldConstraints; import de.symeda.sormas.api.utils.SensitiveData; import de.symeda.sormas.api.utils.YesNoUnknown; @@ -50,11 +50,8 @@ public class PortHealthInfoDto extends EntityDto { @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String flightNumber; - @SensitiveData private Date departureDateTime; - @SensitiveData private Date arrivalDateTime; - @SensitiveData private YesNoUnknown freeSeating; @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) @@ -95,7 +92,6 @@ public class PortHealthInfoDto extends EntityDto { private String lastPortOfCall; // Ground Crossing - @SensitiveData private ConveyanceType conveyanceType; @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoFacadeEjb.java index b3607e5165d..0b6da582538 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoFacadeEjb.java @@ -3,35 +3,23 @@ import javax.ejb.EJB; import javax.ejb.LocalBean; import javax.ejb.Stateless; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Join; -import javax.persistence.criteria.JoinType; -import javax.persistence.criteria.Root; import javax.validation.constraints.NotNull; import de.symeda.sormas.api.caze.porthealthinfo.PortHealthInfoDto; import de.symeda.sormas.api.caze.porthealthinfo.PortHealthInfoFacade; import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.i18n.I18nProperties; -import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.user.UserService; import de.symeda.sormas.backend.util.DtoHelper; -import de.symeda.sormas.backend.util.ModelConstants; import de.symeda.sormas.backend.util.Pseudonymizer; -import de.symeda.sormas.backend.util.QueryHelper; @Stateless(name = "PortHealthInfoFacade") public class PortHealthInfoFacadeEjb implements PortHealthInfoFacade { - @PersistenceContext(unitName = ModelConstants.PERSISTENCE_UNIT_NAME) - private EntityManager em; - @EJB - private UserService userService; @EJB private PortHealthInfoService portHealthInfoService; + @EJB + private UserService userService; public static PortHealthInfoDto toDto(PortHealthInfo source) { if (source == null) { @@ -98,16 +86,8 @@ public PortHealthInfo fillOrBuildEntity(@NotNull PortHealthInfoDto source, PortH @Override public PortHealthInfoDto getByCaseUuid(String caseUuid) { - CriteriaBuilder cb = em.getCriteriaBuilder(); - CriteriaQuery cq = cb.createQuery(PortHealthInfo.class); - Root root = cq.from(Case.class); - Join portHealthJoin = root.join(Case.PORT_HEALTH_INFO, JoinType.LEFT); - - cq.select(portHealthJoin); - cq.where(cb.equal(root.get(Case.UUID), caseUuid)); - PortHealthInfo portHealthInfo = QueryHelper.getSingleResult(em, cq); - return toPseudonymizedDto(portHealthInfo); + return toPseudonymizedDto(portHealthInfoService.getByCaseUuid(caseUuid)); } private PortHealthInfoDto toPseudonymizedDto(PortHealthInfo portHealthInfo) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoService.java index 900ffcd2a23..6d5e8e06fad 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoService.java @@ -2,21 +2,44 @@ import javax.ejb.LocalBean; import javax.ejb.Stateless; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.From; +import javax.persistence.criteria.Join; +import javax.persistence.criteria.JoinType; import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; +import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.common.AdoServiceWithUserFilterAndJurisdiction; +import de.symeda.sormas.backend.util.ModelConstants; +import de.symeda.sormas.backend.util.QueryHelper; @Stateless @LocalBean public class PortHealthInfoService extends AdoServiceWithUserFilterAndJurisdiction { + @PersistenceContext(unitName = ModelConstants.PERSISTENCE_UNIT_NAME) + private EntityManager em; + public PortHealthInfoService() { super(PortHealthInfo.class); } + public PortHealthInfo getByCaseUuid(String caseUuid) { + + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(PortHealthInfo.class); + Root root = cq.from(Case.class); + Join portHealthJoin = root.join(Case.PORT_HEALTH_INFO, JoinType.LEFT); + + cq.select(portHealthJoin); + cq.where(cb.equal(root.get(Case.UUID), caseUuid)); + return QueryHelper.getSingleResult(em, cq); + } + @Override public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { return null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryFacadeEjb.java index 885f2bbcc86..72d4b1d8687 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryFacadeEjb.java @@ -36,8 +36,6 @@ import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.api.utils.SortProperty; import de.symeda.sormas.api.utils.ValidationRuntimeException; -import de.symeda.sormas.backend.caze.Case; -import de.symeda.sormas.backend.caze.CaseJoins; import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb.FeatureConfigurationFacadeEjbLocal; import de.symeda.sormas.backend.infrastructure.AbstractInfrastructureFacadeEjb; import de.symeda.sormas.backend.infrastructure.district.District; @@ -225,32 +223,14 @@ public List getIndexList(PointOfEntryCriteria criteria, Integer @Override public PointOfEntryDto getByCaseUuid(String caseUuid) { - CriteriaBuilder cb = em.getCriteriaBuilder(); - CriteriaQuery cq = cb.createQuery(PointOfEntry.class); - Root root = cq.from(Case.class); - CaseJoins caseCaseJoins = new CaseJoins(root); - Join pointOfEntryJoin = caseCaseJoins.getPointOfEntry(); - - cq.select(pointOfEntryJoin); - cq.where(cb.equal(root.get(Case.UUID), caseUuid)); - PointOfEntry pointOfEntry = QueryHelper.getSingleResult(em, cq); - return toPseudonymizedDto(pointOfEntry); + return toPseudonymizedDto(service.getByCaseUuid(caseUuid)); } @Override public boolean existsForCase(String caseUuid) { - CriteriaBuilder cb = em.getCriteriaBuilder(); - CriteriaQuery cq = cb.createQuery(Boolean.class); - Root root = cq.from(Case.class); - CaseJoins caseCaseJoins = new CaseJoins(root); - Join pointOfEntryJoin = caseCaseJoins.getPointOfEntry(); - - cq.select(cb.literal(true)); - cq.where(cb.and(cb.equal(root.get(Case.UUID), caseUuid), cb.isNotNull(pointOfEntryJoin.get(PointOfEntry.ID)))); - Boolean exist = QueryHelper.getSingleResult(em, cq); - return Boolean.TRUE.equals(exist); + return service.existsForCase(caseUuid); } @Override diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryService.java index ef1a3b10d8e..55014f79ac3 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryService.java @@ -8,6 +8,7 @@ import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.From; +import javax.persistence.criteria.Join; import javax.persistence.criteria.JoinType; import javax.persistence.criteria.Path; import javax.persistence.criteria.Predicate; @@ -19,20 +20,20 @@ import de.symeda.sormas.api.infrastructure.pointofentry.PointOfEntryDto; import de.symeda.sormas.api.infrastructure.pointofentry.PointOfEntryType; import de.symeda.sormas.api.utils.DataHelper; +import de.symeda.sormas.backend.caze.Case; +import de.symeda.sormas.backend.caze.CaseJoins; import de.symeda.sormas.backend.common.AbstractInfrastructureAdoService; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; import de.symeda.sormas.backend.infrastructure.country.Country; import de.symeda.sormas.backend.infrastructure.country.CountryFacadeEjb.CountryFacadeEjbLocal; import de.symeda.sormas.backend.infrastructure.district.District; import de.symeda.sormas.backend.infrastructure.region.Region; -import de.symeda.sormas.backend.infrastructure.region.RegionService; +import de.symeda.sormas.backend.util.QueryHelper; @Stateless @LocalBean public class PointOfEntryService extends AbstractInfrastructureAdoService { - @EJB - private RegionService regionService; @EJB private CountryFacadeEjbLocal countryFacade; @@ -88,17 +89,44 @@ public List getByExternalId(String externalId, boolean includeArch return getByExternalId(externalId, PointOfEntry.EXTERNAL_ID, includeArchivedEntities); } + public PointOfEntry getByCaseUuid(String caseUuid) { + + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(PointOfEntry.class); + Root root = cq.from(Case.class); + CaseJoins caseCaseJoins = new CaseJoins(root); + Join pointOfEntryJoin = caseCaseJoins.getPointOfEntry(); + + cq.select(pointOfEntryJoin); + cq.where(cb.equal(root.get(Case.UUID), caseUuid)); + return QueryHelper.getSingleResult(em, cq); + } + + public boolean existsForCase(String caseUuid) { + + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(Boolean.class); + Root root = cq.from(Case.class); + CaseJoins caseCaseJoins = new CaseJoins(root); + Join pointOfEntryJoin = caseCaseJoins.getPointOfEntry(); + + cq.select(cb.literal(true)); + cq.where(cb.and(cb.equal(root.get(Case.UUID), caseUuid), cb.isNotNull(pointOfEntryJoin.get(PointOfEntry.ID)))); + + return QueryHelper.getSingleResult(em, cq); + } + @Override public Predicate buildCriteriaFilter(PointOfEntryCriteria criteria, CriteriaBuilder cb, Root root) { // ignore Poe created at startup through createConstantPointsOfEntry Predicate excludeConstantPoe = cb.and( - cb.notEqual(root.get(PointOfEntry.UUID), PointOfEntryDto.OTHER_AIRPORT_UUID), - cb.notEqual(root.get(PointOfEntry.UUID), PointOfEntryDto.OTHER_SEAPORT_UUID), - cb.notEqual(root.get(PointOfEntry.UUID), PointOfEntryDto.OTHER_GROUND_CROSSING_UUID), - cb.notEqual(root.get(PointOfEntry.UUID), PointOfEntryDto.OTHER_POE_UUID)); + cb.notEqual(root.get(PointOfEntry.UUID), PointOfEntryDto.OTHER_AIRPORT_UUID), + cb.notEqual(root.get(PointOfEntry.UUID), PointOfEntryDto.OTHER_SEAPORT_UUID), + cb.notEqual(root.get(PointOfEntry.UUID), PointOfEntryDto.OTHER_GROUND_CROSSING_UUID), + cb.notEqual(root.get(PointOfEntry.UUID), PointOfEntryDto.OTHER_POE_UUID)); - if (criteria==null){ + if (criteria == null) { return excludeConstantPoe; } @@ -123,10 +151,8 @@ public Predicate buildCriteriaFilter(PointOfEntryCriteria criteria, CriteriaBuil .and(cb, filter, cb.equal(root.join(PointOfEntry.REGION, JoinType.LEFT).get(Region.UUID), criteria.getRegion().getUuid())); } if (criteria.getDistrict() != null) { - filter = CriteriaBuilderHelper.and( - cb, - filter, - cb.equal(root.join(PointOfEntry.DISTRICT, JoinType.LEFT).get(District.UUID), criteria.getDistrict().getUuid())); + filter = CriteriaBuilderHelper + .and(cb, filter, cb.equal(root.join(PointOfEntry.DISTRICT, JoinType.LEFT).get(District.UUID), criteria.getDistrict().getUuid())); } if (criteria.getType() != null) { filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(root.get(PointOfEntry.POINT_OF_ENTRY_TYPE), criteria.getType())); @@ -147,10 +173,8 @@ public Predicate buildCriteriaFilter(PointOfEntryCriteria criteria, CriteriaBuil } if (criteria.getRelevanceStatus() != null) { if (criteria.getRelevanceStatus() == EntityRelevanceStatus.ACTIVE) { - filter = CriteriaBuilderHelper.and( - cb, - filter, - cb.or(cb.equal(root.get(PointOfEntry.ARCHIVED), false), cb.isNull(root.get(PointOfEntry.ARCHIVED)))); + filter = CriteriaBuilderHelper + .and(cb, filter, cb.or(cb.equal(root.get(PointOfEntry.ARCHIVED), false), cb.isNull(root.get(PointOfEntry.ARCHIVED)))); } else if (criteria.getRelevanceStatus() == EntityRelevanceStatus.ARCHIVED) { filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(root.get(PointOfEntry.ARCHIVED), true)); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/porthealthinfo/PortHealthInfoForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/porthealthinfo/PortHealthInfoForm.java index ac6f2fe18ac..d370bc333cf 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/porthealthinfo/PortHealthInfoForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/porthealthinfo/PortHealthInfoForm.java @@ -15,6 +15,7 @@ import de.symeda.sormas.api.caze.CaseDataDto; import de.symeda.sormas.api.caze.porthealthinfo.ConveyanceType; import de.symeda.sormas.api.caze.porthealthinfo.PortHealthInfoDto; +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; @@ -27,6 +28,7 @@ import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; import de.symeda.sormas.ui.UserProvider; import de.symeda.sormas.ui.utils.AbstractEditForm; +import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.DateComparisonValidator; import de.symeda.sormas.ui.utils.DateTimeField; import de.symeda.sormas.ui.utils.FieldHelper; @@ -73,16 +75,18 @@ public class PortHealthInfoForm extends AbstractEditForm { private PointOfEntryDto pointOfEntry; private String pointOfEntryDetails; + private boolean pseudonymized; - public PortHealthInfoForm(PointOfEntryDto pointOfEntry, String pointOfEntryDetails, boolean isPseudonymized, boolean inJurisdiction) { + public PortHealthInfoForm(PointOfEntryDto pointOfEntry, String pointOfEntryDetails, boolean pseudonymized, boolean inJurisdiction) { super( PortHealthInfoDto.class, PortHealthInfoDto.I18N_PREFIX, false, FieldVisibilityCheckers.withCountry(FacadeProvider.getConfigFacade().getCountryLocale()), - UiFieldAccessCheckers.forDataAccessLevel(UserProvider.getCurrent().getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized)); + UiFieldAccessCheckers.forDataAccessLevel(UserProvider.getCurrent().getPseudonymizableDataAccessLevel(inJurisdiction), pseudonymized)); this.pointOfEntry = pointOfEntry; this.pointOfEntryDetails = pointOfEntryDetails; + this.pseudonymized = pseudonymized; addFields(); } @@ -103,7 +107,13 @@ protected void addFields() { tfPointOfEntryType.setCaption(I18nProperties.getPrefixCaption(PointOfEntryDto.I18N_PREFIX, PointOfEntryDto.POINT_OF_ENTRY_TYPE)); tfPointOfEntryType.setReadOnly(true); TextField tfPointOfEntry = addCustomField(CaseDataDto.POINT_OF_ENTRY, PointOfEntryReferenceDto.class, TextField.class); - tfPointOfEntry.setValue(InfrastructureHelper.buildPointOfEntryString(pointOfEntry.getUuid(), pointOfEntry.getName(), pointOfEntryDetails)); + if (!pseudonymized) { + tfPointOfEntry + .setValue(InfrastructureHelper.buildPointOfEntryString(pointOfEntry.getUuid(), pointOfEntry.getName(), pointOfEntryDetails)); + } else { + tfPointOfEntry.setValue(I18nProperties.getCaption(Captions.inaccessibleValue)); + tfPointOfEntry.addStyleName(CssStyles.INACCESSIBLE_LABEL); + } tfPointOfEntry.setCaption(I18nProperties.getPrefixCaption(CaseDataDto.I18N_PREFIX, CaseDataDto.POINT_OF_ENTRY)); tfPointOfEntry.setReadOnly(true); From f8968d79de0d52c0c106ffe91070ffd6f0d99255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=A9=20Strysewske?= Date: Tue, 3 Jan 2023 12:10:38 +0100 Subject: [PATCH 053/166] #9360 - NullPointer fix --- .../infrastructure/pointofentry/PointOfEntryService.java | 2 +- .../backend/infrastructure/PointOfEntryFacadeEjbTest.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryService.java index 55014f79ac3..7f15c5c5e09 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/pointofentry/PointOfEntryService.java @@ -113,7 +113,7 @@ public boolean existsForCase(String caseUuid) { cq.select(cb.literal(true)); cq.where(cb.and(cb.equal(root.get(Case.UUID), caseUuid), cb.isNotNull(pointOfEntryJoin.get(PointOfEntry.ID)))); - return QueryHelper.getSingleResult(em, cq); + return Boolean.TRUE.equals(QueryHelper.getSingleResult(em, cq)); } @Override diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PointOfEntryFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PointOfEntryFacadeEjbTest.java index 2ed37a872ba..3693c008a63 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PointOfEntryFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/infrastructure/PointOfEntryFacadeEjbTest.java @@ -74,7 +74,7 @@ void testCount() { } @Test - public void testGetPointOfEntryByCaseUuid() { + void testGetPointOfEntryByCaseUuid() { RDCF rdcf = creator.createRDCF(); UserDto user = creator.createUser(rdcf, creator.getUserRoleReference(DefaultUserRole.NATIONAL_USER)); PersonDto personDto = creator.createPerson("John", "Doe"); @@ -96,7 +96,7 @@ public void testGetPointOfEntryByCaseUuid() { } @Test - public void testExistForCase() { + void testExistForCase() { RDCF rdcf = creator.createRDCF(); UserDto user = creator.createUser(rdcf, creator.getUserRoleReference(DefaultUserRole.NATIONAL_USER)); PersonDto personDto = creator.createPerson("John", "Doe"); From e28b9a2bfd94d4c883d7f97cda8b71a4dfcb1e54 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Tue, 3 Jan 2023 12:24:58 +0100 Subject: [PATCH 054/166] fixes --- .../pages/application/tasks/TaskManagementPage.java | 6 ++++++ .../web/application/tasks/TaskManagementSteps.java | 12 ++++-------- .../test/resources/features/sanity/web/Task.feature | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/tasks/TaskManagementPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/tasks/TaskManagementPage.java index f1fce174b99..31674d3dcd4 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/tasks/TaskManagementPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/tasks/TaskManagementPage.java @@ -81,4 +81,10 @@ public static By getCustomExportByID(String id) { public static By getEditTaskButtonByNumber(Integer number) { return By.xpath(String.format("//table/tbody/tr[%x]/td[1]", number)); } + + public static By getLastCreatedEditTaskButton(String text) { + return By.xpath( + String.format( + "//td[contains(text(),'%s')]/../td/span[contains(@class, 'v-icon-edit')]", text)); + } } diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/tasks/TaskManagementSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/tasks/TaskManagementSteps.java index 8a26b1fedc1..4a518a30936 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/tasks/TaskManagementSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/tasks/TaskManagementSteps.java @@ -99,20 +99,16 @@ public TaskManagementSteps( When( "^I open last created task from Tasks Directory$", () -> { - By lastTaskEditButton = - By.xpath( - String.format( - EDIT_BUTTON_XPATH_BY_TEXT, CreateNewTaskSteps.task.getCommentsOnExecution())); webDriverHelpers.clickOnWebElementBySelector(SHOW_MORE_FILTERS); webDriverHelpers.waitUntilIdentifiedElementIsVisibleAndClickable( ASSIGNED_USER_FILTER_INPUT); String assignedUser = CreateNewTaskSteps.task.getAssignedTo(); webDriverHelpers.fillInWebElement(ASSIGNED_USER_FILTER_INPUT, assignedUser); webDriverHelpers.clickOnWebElementBySelector(APPLY_FILTER); - webDriverHelpers.waitUntilIdentifiedElementIsVisibleAndClickable(lastTaskEditButton, 40); - TimeUnit.SECONDS.sleep(3); - webDriverHelpers.clickElementSeveralTimesUntilNextElementIsDisplayed( - lastTaskEditButton, TASK_STATUS_OPTIONS, 6); + webDriverHelpers.waitForPageLoadingSpinnerToDisappear(60); + webDriverHelpers.clickOnWebElementBySelector( + getLastCreatedEditTaskButton(CreateNewTaskSteps.task.getCommentsOnExecution())); + webDriverHelpers.waitForPageLoadingSpinnerToDisappear(60); }); When( "^I filter out last created task from Tasks Directory$", diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Task.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Task.feature index bb51db50054..fc4f22b5447 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Task.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Task.feature @@ -155,7 +155,7 @@ Feature: Tasks functionalities And I select "Contact OFFICER" user from Observed by combobox in new Task form And I delete "Contact OFFICER" user from Observed by in new Task form And I click on Save button in New Task form - And I click on edit task icon of the 1 displayed task on Task Directory page + When I open last created task from Tasks Directory Then I check that National CLINICIAN is visible in Observed By on Edit Task Page And I check that Surveillance SUPERVISOR is visible in Observed By on Edit Task Page And I check that Contact OFFICER is not visible in Observed By on Edit Task Page From 644f717f43b1b6251fe76a3cc6e7b46375806f78 Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Tue, 3 Jan 2023 15:16:13 +0100 Subject: [PATCH 055/166] fix --- .../entries/TravelEntryDirectorySteps.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/entries/TravelEntryDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/entries/TravelEntryDirectorySteps.java index 73c81523aaa..95ba6ffd922 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/entries/TravelEntryDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/entries/TravelEntryDirectorySteps.java @@ -347,9 +347,11 @@ public TravelEntryDirectorySteps( "I apply the last epi week for week from combobox on Travel Entry directory page", () -> { int week = - CreateNewTravelEntrySteps.previousWeekDate.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR) - + 1; // because weeks are counting since end of december previous year - String lastEpiWeek = "Wo " + week + "-" + LocalDate.now().getYear(); + CreateNewTravelEntrySteps.previousWeekDate.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR); + // + 1; // because weeks are counting since end of december previous year + + LocalDate newYearSuprise = LocalDate.now().minusDays(7); + String lastEpiWeek = "Wo " + week + "-" + newYearSuprise.getYear(); webDriverHelpers.selectFromCombobox(WEEK_FROM_OPTION_COMBOBOX, lastEpiWeek); }); @@ -359,6 +361,8 @@ public TravelEntryDirectorySteps( int week = CreateNewTravelEntrySteps.previousWeekDate.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR) + 1; // because weeks are counting since end of december previous year + if (week == 53) week = 1; + LocalDate newYearSuprise = LocalDate.now().minusDays(7); String lastEpiWeek = "Wo " + week + "-" + LocalDate.now().getYear(); webDriverHelpers.selectFromCombobox(WEEK_TO_OPTION_COMBOBOX, lastEpiWeek); }); @@ -367,7 +371,11 @@ public TravelEntryDirectorySteps( () -> { int week = CreateNewTravelEntrySteps.previousWeekDate.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR); - String lastEpiWeek = "Wo " + week + "-" + LocalDate.now().getYear(); + if (week == 53) week = 1; + + LocalDate newYearSuprise = LocalDate.now().minusDays(7); + + String lastEpiWeek = "Wo " + week + "-" + newYearSuprise.getYear(); webDriverHelpers.selectFromCombobox(WEEK_TO_OPTION_COMBOBOX, lastEpiWeek); }); From 925ab50a20074486ecfb5e418bb304263103e35a Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Tue, 3 Jan 2023 15:34:34 +0100 Subject: [PATCH 056/166] fixes --- .../web/application/entries/CreateNewTravelEntrySteps.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/entries/CreateNewTravelEntrySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/entries/CreateNewTravelEntrySteps.java index 16f386ea25c..8e05567ccc5 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/entries/CreateNewTravelEntrySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/entries/CreateNewTravelEntrySteps.java @@ -707,7 +707,7 @@ public CreateNewTravelEntrySteps( webDriverHelpers.isElementDisplayedIn20SecondsOrThrowException( By.xpath( "//div[text()='Automated test dummy description " - + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-M-dd")) + + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + "']")); }); From 36c4151f27351a8ec33b9dc12f09060f490d1520 Mon Sep 17 00:00:00 2001 From: Levente Gal <62599627+leventegal-she@users.noreply.github.com> Date: Tue, 3 Jan 2023 17:47:57 +0200 Subject: [PATCH 057/166] =?UTF-8?q?#8727=20Tasks=20associated=20with=20arc?= =?UTF-8?q?hived=20entities=20should=20be=20'read=20only'=20-=E2=80=A6=20(?= =?UTF-8?q?#11172)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * #8727 Tasks associated with archived entities should be 'read only' - don't allow tasks archived or linked to archived entity to be edited --- .../symeda/sormas/api/EditPermissionType.java | 2 +- .../de/symeda/sormas/api/task/TaskFacade.java | 3 + .../sormas/backend/caze/CaseService.java | 2 +- .../backend/contact/ContactService.java | 2 +- .../sormas/backend/event/EventService.java | 6 +- .../sormas/backend/task/TaskFacadeEjb.java | 6 + .../sormas/backend/task/TaskService.java | 33 ++- .../backend/task/TaskFacadeEjbTest.java | 225 ++++++++++++++++++ .../symeda/sormas/ui/caze/CaseDataView.java | 4 +- .../sormas/ui/contact/ContactDataView.java | 4 +- .../sormas/ui/events/EventDataView.java | 2 +- .../symeda/sormas/ui/task/TaskController.java | 40 ++-- .../de/symeda/sormas/ui/task/TaskGrid.java | 2 +- .../ui/travelentry/TravelEntryDataView.java | 2 +- 14 files changed, 300 insertions(+), 33 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/EditPermissionType.java b/sormas-api/src/main/java/de/symeda/sormas/api/EditPermissionType.java index 94565bb1cf2..2beb903d84f 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/EditPermissionType.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/EditPermissionType.java @@ -4,5 +4,5 @@ public enum EditPermissionType { ALLOWED, ARCHIVING_STATUS_ONLY, REFUSED, - DOCUMENTS_ONLY + WITHOUT_OWNERSHIP } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/task/TaskFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/task/TaskFacade.java index 6d2d5f60ea0..68a050b62bb 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/task/TaskFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/task/TaskFacade.java @@ -25,6 +25,7 @@ import javax.ejb.Remote; import javax.validation.Valid; +import de.symeda.sormas.api.EditPermissionType; import de.symeda.sormas.api.caze.CaseReferenceDto; import de.symeda.sormas.api.common.Page; import de.symeda.sormas.api.contact.ContactReferenceDto; @@ -83,4 +84,6 @@ public interface TaskFacade { List getArchivedUuidsSince(Date since); List getObsoleteUuidsSince(Date since); + + EditPermissionType getEditPermissionType(String uuid); } 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 df8ef4b53e4..5b6e98cd1ca 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 @@ -1609,7 +1609,7 @@ public EditPermissionType getEditPermissionType(Case caze) { } if (sormasToSormasShareInfoService.isCaseOwnershipHandedOver(caze)) { - return EditPermissionType.DOCUMENTS_ONLY; + return EditPermissionType.WITHOUT_OWNERSHIP; } return super.getEditPermissionType(caze); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java index f6072873539..569fad96b43 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java @@ -1664,7 +1664,7 @@ public EditPermissionType getEditPermissionType(Contact contact) { } if (sormasToSormasShareInfoService.isContactOwnershipHandedOver(contact)) { - return EditPermissionType.DOCUMENTS_ONLY; + return EditPermissionType.WITHOUT_OWNERSHIP; } return super.getEditPermissionType(contact); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java index 02a0edf2ae3..e5a43751559 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java @@ -1005,10 +1005,14 @@ public EditPermissionType getEditPermissionType(Event event) { return EditPermissionType.REFUSED; } - if (!inJurisdictionOrOwned(event) || sormasToSormasShareInfoService.isEventOwnershipHandedOver(event)) { + if (!inJurisdictionOrOwned(event)) { return EditPermissionType.REFUSED; } + if (sormasToSormasShareInfoService.isEventOwnershipHandedOver(event)) { + return EditPermissionType.WITHOUT_OWNERSHIP; + } + return super.getEditPermissionType(event); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskFacadeEjb.java index 27703e92557..ec2f17ce9f7 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskFacadeEjb.java @@ -48,6 +48,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import de.symeda.sormas.api.EditPermissionType; import de.symeda.sormas.api.caze.BirthDateDto; import de.symeda.sormas.api.caze.CaseReferenceDto; import de.symeda.sormas.api.common.Page; @@ -1084,6 +1085,11 @@ private String getUiUrl(TaskContext taskContext, String uuid) { return uiUrlBuilder.append("#!").append(taskContext.getUrlPattern()).append("/data/").append(uuid).toString(); } + @Override + public EditPermissionType getEditPermissionType(String uuid) { + return taskService.getEditPermissionType(taskService.getByUuid(uuid)); + } + @LocalBean @Stateless public static class TaskFacadeEjbLocal extends TaskFacadeEjb { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java index f93749799d1..5a1514b3768 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java @@ -44,6 +44,7 @@ import org.apache.commons.lang3.ArrayUtils; +import de.symeda.sormas.api.EditPermissionType; import de.symeda.sormas.api.EntityRelevanceStatus; import de.symeda.sormas.api.RequestContextHolder; import de.symeda.sormas.api.contact.ContactReferenceDto; @@ -424,7 +425,7 @@ public Predicate buildCriteriaFilter(TaskCriteria taskCriteria, TaskQueryContext cb.or( cb.isTrue(from.get(Task.ARCHIVED)), cb.and(cb.equal(from.get(Task.TASK_CONTEXT), TaskContext.CASE), cb.equal(joins.getCaze().get(Case.ARCHIVED), true)), - cb.and(cb.equal(from.get(Task.TASK_CONTEXT), TaskContext.CONTACT), cb.equal(joins.getContactCase().get(Case.ARCHIVED), true)), + cb.and(cb.equal(from.get(Task.TASK_CONTEXT), TaskContext.CONTACT), cb.equal(joins.getContact().get(Case.ARCHIVED), true)), cb.and(cb.equal(from.get(Task.TASK_CONTEXT), TaskContext.EVENT), cb.equal(joins.getEvent().get(Event.ARCHIVED), true)), cb.and( cb.equal(from.get(Task.TASK_CONTEXT), TaskContext.TRAVEL_ENTRY), @@ -573,7 +574,7 @@ private Predicate buildActiveTasksFilter(TaskQueryContext taskQueryContext) { TaskJoins joins = taskQueryContext.getJoins(); Join caze = joins.getCaze(); - Join contactCaze = joins.getContactCase(); + Join contact = joins.getContact(); Join event = joins.getEvent(); Join travelEntry = joins.getTravelEntry(); @@ -589,8 +590,8 @@ private Predicate buildActiveTasksFilter(TaskQueryContext taskQueryContext) { cb.and( cb.equal(from.get(Task.TASK_CONTEXT), TaskContext.CONTACT), cb.and( - cb.or(cb.isNull(contactCaze.get(Case.ARCHIVED)), cb.isFalse(contactCaze.get(Case.ARCHIVED))), - cb.or(cb.isNull(contactCaze.get(Case.DELETED)), cb.isFalse(contactCaze.get(Case.DELETED))))), + cb.or(cb.isNull(contact.get(Case.ARCHIVED)), cb.isFalse(contact.get(Case.ARCHIVED))), + cb.or(cb.isNull(contact.get(Case.DELETED)), cb.isFalse(contact.get(Case.DELETED))))), cb.and( cb.equal(from.get(Task.TASK_CONTEXT), TaskContext.EVENT), cb.and( @@ -794,4 +795,28 @@ public Predicate inJurisdictionOrOwned(TaskQueryContext qc) { final User currentUser = userService.getCurrentUser(); return TaskJurisdictionPredicateValidator.of(qc, currentUser).inJurisdictionOrOwned(); } + + public EditPermissionType getEditPermissionType(Task task) { + if (task.isArchived()) { + return featureConfigurationFacade.isFeatureEnabled(FeatureType.EDIT_ARCHIVED_ENTITIES) + ? EditPermissionType.ALLOWED + : EditPermissionType.ARCHIVING_STATUS_ONLY; + } + + switch (task.getTaskContext()) { + case CASE: + EditPermissionType casePermissionType = caseService.getEditPermissionType(task.getCaze()); + return casePermissionType == EditPermissionType.WITHOUT_OWNERSHIP ? EditPermissionType.ALLOWED : casePermissionType; + case CONTACT: + EditPermissionType contactPermissionType = contactService.getEditPermissionType(task.getContact()); + return contactPermissionType == EditPermissionType.WITHOUT_OWNERSHIP ? EditPermissionType.ALLOWED : contactPermissionType; + case EVENT: + EditPermissionType eventPermissionType = eventService.getEditPermissionType(task.getEvent()); + return eventPermissionType == EditPermissionType.WITHOUT_OWNERSHIP ? EditPermissionType.ALLOWED : eventPermissionType; + case TRAVEL_ENTRY: + return travelEntryService.getEditPermissionType(task.getTravelEntry()); + } + + return EditPermissionType.ALLOWED; + } } diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/task/TaskFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/task/TaskFacadeEjbTest.java index 6e511d54ce5..80797da04a7 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/task/TaskFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/task/TaskFacadeEjbTest.java @@ -19,6 +19,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -41,6 +42,7 @@ import org.junit.jupiter.api.Test; import de.symeda.sormas.api.Disease; +import de.symeda.sormas.api.EditPermissionType; import de.symeda.sormas.api.EntityDto; import de.symeda.sormas.api.EntityRelevanceStatus; import de.symeda.sormas.api.caze.CaseClassification; @@ -52,8 +54,12 @@ import de.symeda.sormas.api.event.EventInvestigationStatus; import de.symeda.sormas.api.event.EventStatus; import de.symeda.sormas.api.event.TypeOfPlace; +import de.symeda.sormas.api.feature.FeatureConfigurationIndexDto; +import de.symeda.sormas.api.feature.FeatureType; import de.symeda.sormas.api.infrastructure.community.CommunityDto; import de.symeda.sormas.api.person.PersonDto; +import de.symeda.sormas.api.sormastosormas.share.incoming.ShareRequestDataType; +import de.symeda.sormas.api.sormastosormas.share.incoming.ShareRequestStatus; import de.symeda.sormas.api.task.TaskContext; import de.symeda.sormas.api.task.TaskCriteria; import de.symeda.sormas.api.task.TaskDto; @@ -236,12 +242,19 @@ public void testArchivedTaskNotGettingTransfered() { getCaseFacade().archive(caze.getUuid(), null); getEventFacade().archive(event.getUuid(), null); + // getAllActiveTasks and getAllUuids should return length 3 + assertEquals(3, getTaskFacade().getAllActiveTasksAfter(null).size()); + assertEquals(3, getTaskFacade().getAllActiveUuids().size()); + + getContactFacade().archive(contact.getUuid(), null); + // getAllActiveTasks and getAllUuids should return length 1 assertEquals(1, getTaskFacade().getAllActiveTasksAfter(null).size()); assertEquals(1, getTaskFacade().getAllActiveUuids().size()); getCaseFacade().dearchive(Collections.singletonList(caze.getUuid()), null); getEventFacade().dearchive(Collections.singletonList(event.getUuid()), null); + getContactFacade().dearchive(Collections.singletonList(contact.getUuid()), null); // getAllActiveTasks and getAllUuids should return length 5 + 1 (contact investigation) assertEquals(6, getTaskFacade().getAllActiveTasksAfter(null).size()); @@ -727,4 +740,216 @@ public void testUserWithoutEventViewRightSeeHisObservedTask() { assertFalse(tasksIds.contains(taskEvent1.getUuid())); assertTrue(tasksIds.contains(taskEvent2.getUuid())); } + + @Test + public void testGetIndexListArchived() { + RDCF rdcf = creator.createRDCF(); + UserDto user = creator.createUser(rdcf, creator.getUserRoleReference(DefaultUserRole.SURVEILLANCE_OFFICER)); + + TaskDto task = + creator.createTask(TaskContext.GENERAL, TaskType.ANIMAL_TESTING, TaskStatus.PENDING, null, null, null, new Date(), user.toReference()); + getTaskFacade().updateArchived(task.getUuid(), true); + + List archivedTasks = + getTaskFacade().getIndexList(new TaskCriteria().relevanceStatus(EntityRelevanceStatus.ARCHIVED), null, null, null); + + assertThat(archivedTasks, hasSize(1)); + assertThat(archivedTasks.stream().filter(t -> t.getUuid().equals(task.getUuid())).count(), is(1L)); + + CaseDataDto caze = creator.createCase(user.toReference(), rdcf, null); + TaskDto caseTask = creator.createTask(TaskContext.CASE, caze.toReference(), null); + getCaseFacade().archive(caze.getUuid(), new Date()); + + archivedTasks = getTaskFacade().getIndexList(new TaskCriteria().relevanceStatus(EntityRelevanceStatus.ARCHIVED), null, null, null); + assertThat(archivedTasks.stream().filter(t -> t.getUuid().equals(caseTask.getUuid())).count(), is(1L)); + + ContactDto contact = creator.createContact(rdcf, user.toReference(), creator.createPerson().toReference()); + TaskDto contactTask = creator.createTask(TaskContext.CONTACT, contact.toReference(), null); + getContactFacade().archive(contact.getUuid(), new Date()); + + archivedTasks = getTaskFacade().getIndexList(new TaskCriteria().relevanceStatus(EntityRelevanceStatus.ARCHIVED), null, null, null); + assertThat(archivedTasks.stream().filter(t -> t.getUuid().equals(contactTask.getUuid())).count(), is(1L)); + + EventDto event = creator.createEvent(user.toReference()); + TaskDto eventTask = creator.createTask(TaskContext.EVENT, event.toReference(), null); + getEventFacade().archive(event.getUuid(), new Date()); + + archivedTasks = getTaskFacade().getIndexList(new TaskCriteria().relevanceStatus(EntityRelevanceStatus.ARCHIVED), null, null, null); + assertThat(archivedTasks.stream().filter(t -> t.getUuid().equals(eventTask.getUuid())).count(), is(1L)); + + TravelEntryDto travelEntry = creator.createTravelEntry(creator.createPerson().toReference(), user.toReference(), rdcf, null); + TaskDto travelEntryTask = creator.createTask(TaskContext.TRAVEL_ENTRY, travelEntry.toReference(), null); + getTravelEntryFacade().archive(travelEntry.getUuid(), new Date()); + + archivedTasks = getTaskFacade().getIndexList(new TaskCriteria().relevanceStatus(EntityRelevanceStatus.ARCHIVED), null, null, null); + assertThat(archivedTasks.stream().filter(t -> t.getUuid().equals(travelEntryTask.getUuid())).count(), is(1L)); + } + + @Test + public void testGetEditPermissionTypeOnGenericTask() { + RDCF rdcf = creator.createRDCF(); + UserDto user = creator.createUser(rdcf, creator.getUserRoleReference(DefaultUserRole.SURVEILLANCE_OFFICER)); + + TaskDto task = + creator.createTask(TaskContext.GENERAL, TaskType.ANIMAL_TESTING, TaskStatus.PENDING, null, null, null, new Date(), user.toReference()); + assertThat(getTaskFacade().getEditPermissionType(task.getUuid()), is(EditPermissionType.ALLOWED)); + + getTaskFacade().updateArchived(task.getUuid(), true); + setEditArchiveFeature(true); + assertThat(getTaskFacade().getEditPermissionType(task.getUuid()), is(EditPermissionType.ALLOWED)); + setEditArchiveFeature(false); + assertThat(getTaskFacade().getEditPermissionType(task.getUuid()), is(EditPermissionType.ARCHIVING_STATUS_ONLY)); + } + + @Test + public void testGetEditPermissionTypeOnCaseTask() { + RDCF rdcf = creator.createRDCF(); + UserDto user = creator.createUser(rdcf, creator.getUserRoleReference(DefaultUserRole.SURVEILLANCE_OFFICER)); + + CaseDataDto caseToArchive = creator.createCase(user.toReference(), rdcf, null); + TaskDto task = creator.createTask(TaskContext.CASE, caseToArchive.toReference(), null); + assertThat(getTaskFacade().getEditPermissionType(task.getUuid()), is(EditPermissionType.ALLOWED)); + + getCaseFacade().archive(caseToArchive.getUuid(), new Date()); + + setEditArchiveFeature(true); + assertThat(getTaskFacade().getEditPermissionType(task.getUuid()), is(EditPermissionType.ALLOWED)); + + setEditArchiveFeature(false); + assertThat(getTaskFacade().getEditPermissionType(task.getUuid()), is(EditPermissionType.ARCHIVING_STATUS_ONLY)); + + // shared case + CaseDataDto caseToShare = creator.createCase(user.toReference(), rdcf, null); + task = creator.createTask(TaskContext.CASE, caseToShare.toReference(), null); + + creator.createShareRequestInfo( + ShareRequestDataType.CASE, + getUserService().getByUuid(user.getUuid()), + "test-server", + true, + ShareRequestStatus.PENDING, + (s) -> s.setCaze(getCaseService().getByUuid(caseToShare.getUuid()))); + + assertThat(getTaskFacade().getEditPermissionType(task.getUuid()), is(EditPermissionType.ALLOWED)); + + creator.createShareRequestInfo( + ShareRequestDataType.CASE, + getUserService().getByUuid(user.getUuid()), + "test-server", + true, + ShareRequestStatus.ACCEPTED, + (s) -> s.setCaze(getCaseService().getByUuid(caseToShare.getUuid()))); + + assertThat(getTaskFacade().getEditPermissionType(task.getUuid()), is(EditPermissionType.ALLOWED)); + } + + @Test + public void testGetEditPermissionTypeOnContactTask() { + RDCF rdcf = creator.createRDCF(); + UserDto user = creator.createUser(rdcf, creator.getUserRoleReference(DefaultUserRole.SURVEILLANCE_OFFICER)); + + ContactDto contactToArchive = creator.createContact(rdcf, user.toReference(), creator.createPerson().toReference()); + TaskDto task = creator.createTask(TaskContext.CONTACT, contactToArchive.toReference(), null); + assertThat(getTaskFacade().getEditPermissionType(task.getUuid()), is(EditPermissionType.ALLOWED)); + + getContactFacade().archive(contactToArchive.getUuid(), new Date()); + + setEditArchiveFeature(true); + assertThat(getTaskFacade().getEditPermissionType(task.getUuid()), is(EditPermissionType.ALLOWED)); + + setEditArchiveFeature(false); + assertThat(getTaskFacade().getEditPermissionType(task.getUuid()), is(EditPermissionType.ARCHIVING_STATUS_ONLY)); + + // shared contact + ContactDto contactToShare = creator.createContact(rdcf, user.toReference(), creator.createPerson().toReference()); + task = creator.createTask(TaskContext.CONTACT, contactToShare.toReference(), null); + + creator.createShareRequestInfo( + ShareRequestDataType.CONTACT, + getUserService().getByUuid(user.getUuid()), + "test-server", + true, + ShareRequestStatus.PENDING, + (s) -> s.setContact(getContactService().getByUuid(contactToShare.getUuid()))); + + assertThat(getTaskFacade().getEditPermissionType(task.getUuid()), is(EditPermissionType.ALLOWED)); + + creator.createShareRequestInfo( + ShareRequestDataType.CONTACT, + getUserService().getByUuid(user.getUuid()), + "test-server", + true, + ShareRequestStatus.ACCEPTED, + (s) -> s.setContact(getContactService().getByUuid(contactToShare.getUuid()))); + + assertThat(getTaskFacade().getEditPermissionType(task.getUuid()), is(EditPermissionType.ALLOWED)); + } + + @Test + public void testGetEditPermissionTypeOnEventTask() { + RDCF rdcf = creator.createRDCF(); + UserDto user = creator.createUser(rdcf, creator.getUserRoleReference(DefaultUserRole.SURVEILLANCE_OFFICER)); + + EventDto eventToArchive = creator.createEvent(user.toReference()); + TaskDto task = creator.createTask(TaskContext.EVENT, eventToArchive.toReference(), null); + assertThat(getTaskFacade().getEditPermissionType(task.getUuid()), is(EditPermissionType.ALLOWED)); + + getEventFacade().archive(eventToArchive.getUuid(), new Date()); + + setEditArchiveFeature(true); + assertThat(getTaskFacade().getEditPermissionType(task.getUuid()), is(EditPermissionType.ALLOWED)); + + setEditArchiveFeature(false); + assertThat(getTaskFacade().getEditPermissionType(task.getUuid()), is(EditPermissionType.ARCHIVING_STATUS_ONLY)); + + // shared event + EventDto eventToShare = creator.createEvent(user.toReference()); + task = creator.createTask(TaskContext.EVENT, eventToShare.toReference(), null); + + creator.createShareRequestInfo( + ShareRequestDataType.EVENT, + getUserService().getByUuid(user.getUuid()), + "test-server", + true, + ShareRequestStatus.PENDING, + (s) -> s.setEvent(getEventService().getByUuid(eventToShare.getUuid()))); + + assertThat(getTaskFacade().getEditPermissionType(task.getUuid()), is(EditPermissionType.ALLOWED)); + + creator.createShareRequestInfo( + ShareRequestDataType.EVENT, + getUserService().getByUuid(user.getUuid()), + "test-server", + true, + ShareRequestStatus.ACCEPTED, + (s) -> s.setEvent(getEventService().getByUuid(eventToShare.getUuid()))); + + assertThat(getTaskFacade().getEditPermissionType(task.getUuid()), is(EditPermissionType.ALLOWED)); + } + + @Test + public void testGetEditPermissionTypeOnTravelEntryTask() { + RDCF rdcf = creator.createRDCF(); + UserDto user = creator.createUser(rdcf, creator.getUserRoleReference(DefaultUserRole.SURVEILLANCE_OFFICER)); + + TravelEntryDto travelEntryToArchive = creator.createTravelEntry(creator.createPerson().toReference(), user.toReference(), rdcf, null); + TaskDto task = creator.createTask(TaskContext.TRAVEL_ENTRY, travelEntryToArchive.toReference(), null); + assertThat(getTaskFacade().getEditPermissionType(task.getUuid()), is(EditPermissionType.ALLOWED)); + + getTravelEntryFacade().archive(travelEntryToArchive.getUuid(), new Date()); + + setEditArchiveFeature(true); + assertThat(getTaskFacade().getEditPermissionType(task.getUuid()), is(EditPermissionType.ALLOWED)); + + setEditArchiveFeature(false); + assertThat(getTaskFacade().getEditPermissionType(task.getUuid()), is(EditPermissionType.ARCHIVING_STATUS_ONLY)); + } + + private void setEditArchiveFeature(boolean enabled) { + FeatureConfigurationIndexDto featureConfiguration = + new FeatureConfigurationIndexDto(DataHelper.createUuid(), null, null, null, null, null, enabled, null); + getFeatureConfigurationFacade().saveFeatureConfiguration(featureConfiguration, FeatureType.EDIT_ARCHIVED_ENTITIES); + + } + } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataView.java index 12f92711bca..dbb4e240310 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataView.java @@ -205,7 +205,7 @@ protected void initView(String params) { && UserProvider.getCurrent().hasUserRight(UserRight.DOCUMENT_VIEW)) { boolean isDocumentDeleteAllowed = - EditPermissionType.ALLOWED.equals(caseEditAllowed) || EditPermissionType.DOCUMENTS_ONLY.equals(caseEditAllowed); + EditPermissionType.ALLOWED.equals(caseEditAllowed) || EditPermissionType.WITHOUT_OWNERSHIP.equals(caseEditAllowed); documentList = new DocumentListComponent( DocumentRelatedEntityType.CASE, getCaseRef(), @@ -226,7 +226,7 @@ protected void initView(String params) { layout.disableWithViewAllow(ArchivingController.ARCHIVE_DEARCHIVE_BUTTON_ID); } else if (caseEditAllowed.equals(EditPermissionType.REFUSED)) { layout.disableWithViewAllow(); - } else if (caseEditAllowed.equals(EditPermissionType.DOCUMENTS_ONLY)) { + } else if (caseEditAllowed.equals(EditPermissionType.WITHOUT_OWNERSHIP)) { layout.disableWithViewAllow(); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactDataView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactDataView.java index 877744e9089..48d2377548d 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactDataView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactDataView.java @@ -272,7 +272,7 @@ protected void initView(String params) { if (FacadeProvider.getFeatureConfigurationFacade().isFeatureEnabled(FeatureType.DOCUMENTS) && UserProvider.getCurrent().hasUserRight(UserRight.DOCUMENT_VIEW)) { boolean isDocumentDeleteAllowed = - EditPermissionType.ALLOWED.equals(contactEditAllowed) || EditPermissionType.DOCUMENTS_ONLY.equals(contactEditAllowed); + EditPermissionType.ALLOWED.equals(contactEditAllowed) || EditPermissionType.WITHOUT_OWNERSHIP.equals(contactEditAllowed); documentList = new DocumentListComponent( DocumentRelatedEntityType.CONTACT, getContactRef(), @@ -293,7 +293,7 @@ protected void initView(String params) { layout.disableWithViewAllow(ArchivingController.ARCHIVE_DEARCHIVE_BUTTON_ID); } else if (contactEditAllowed.equals(EditPermissionType.REFUSED)) { layout.disableWithViewAllow(); - } else if (contactEditAllowed.equals(EditPermissionType.DOCUMENTS_ONLY)) { + } else if (contactEditAllowed.equals(EditPermissionType.WITHOUT_OWNERSHIP)) { layout.disableWithViewAllow(); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventDataView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventDataView.java index 1b42a02f9fd..01afc2705db 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventDataView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventDataView.java @@ -132,7 +132,7 @@ protected void initView(String params) { && UserProvider.getCurrent().hasUserRight(UserRight.DOCUMENT_VIEW)) { boolean isDocumentDeleteAllowed = - EditPermissionType.ALLOWED.equals(eventEditAllowed) || EditPermissionType.DOCUMENTS_ONLY.equals(eventEditAllowed); + EditPermissionType.ALLOWED.equals(eventEditAllowed) || EditPermissionType.WITHOUT_OWNERSHIP.equals(eventEditAllowed); documentList = new DocumentListComponent( DocumentRelatedEntityType.EVENT, getEventRef(), diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskController.java index a9a610b3e95..08d3d1cc477 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskController.java @@ -32,6 +32,7 @@ import com.vaadin.ui.themes.ValoTheme; import de.symeda.sormas.api.Disease; +import de.symeda.sormas.api.EditPermissionType; import de.symeda.sormas.api.FacadeProvider; import de.symeda.sormas.api.ReferenceDto; import de.symeda.sormas.api.i18n.Captions; @@ -100,33 +101,34 @@ public void createSampleCollectionTask(TaskContext context, ReferenceDto entityR VaadinUiUtil.showModalPopupWindow(createView, I18nProperties.getString(Strings.headingCreateNewTask)); } - public void edit(TaskIndexDto dto, Runnable callback, boolean editedFromTaskGrid, Disease disease) { + public void edit(TaskIndexDto taskIndex, Runnable callback, boolean editedFromTaskGrid, Disease disease) { // get fresh data - TaskDto newDto = FacadeProvider.getTaskFacade().getByUuid(dto.getUuid()); + TaskDto task = FacadeProvider.getTaskFacade().getByUuid(taskIndex.getUuid()); TaskEditForm form = new TaskEditForm(false, editedFromTaskGrid, disease); - form.setValue(newDto); + form.setValue(task); + + EditPermissionType editPermissionType = FacadeProvider.getTaskFacade().getEditPermissionType(task.getUuid()); + boolean isEditingAllowed = UserProvider.getCurrent().hasUserRight(UserRight.TASK_EDIT) && editPermissionType == EditPermissionType.ALLOWED; + final CommitDiscardWrapperComponent editView = - new CommitDiscardWrapperComponent(form, UserProvider.getCurrent().hasUserRight(UserRight.TASK_EDIT), form.getFieldGroup()); - editView.getButtonsPanel().setVisible(UserProvider.getCurrent().hasUserRight(UserRight.TASK_EDIT)); + new CommitDiscardWrapperComponent(form, true, form.getFieldGroup()); Window popupWindow = VaadinUiUtil.showModalPopupWindow( editView, - UserProvider.getCurrent().hasUserRight(UserRight.TASK_EDIT) - ? I18nProperties.getString(Strings.headingEditTask) - : I18nProperties.getString(Strings.headingViewTask)); + isEditingAllowed ? I18nProperties.getString(Strings.headingEditTask) : I18nProperties.getString(Strings.headingViewTask)); editView.addCommitListener(() -> { if (!form.getFieldGroup().isModified()) { - TaskDto dto1 = form.getValue(); - if (!dto1.getAssigneeUser().getUuid().equals(dto.getAssigneeUser().getUuid())) { - dto1.setAssignedByUser(UserProvider.getCurrent().getUserReference()); + TaskDto formValue = form.getValue(); + if (!formValue.getAssigneeUser().getUuid().equals(taskIndex.getAssigneeUser().getUuid())) { + formValue.setAssignedByUser(UserProvider.getCurrent().getUserReference()); } - FacadeProvider.getTaskFacade().saveTask(dto1); + FacadeProvider.getTaskFacade().saveTask(formValue); - if (!editedFromTaskGrid && dto1.getCaze() != null) { - ControllerProvider.getCaseController().navigateToCase(dto1.getCaze().getUuid()); + if (!editedFromTaskGrid && formValue.getCaze() != null) { + ControllerProvider.getCaseController().navigateToCase(formValue.getCaze().getUuid()); } popupWindow.close(); @@ -138,7 +140,7 @@ public void edit(TaskIndexDto dto, Runnable callback, boolean editedFromTaskGrid if (UserProvider.getCurrent().hasUserRight(UserRight.TASK_DELETE)) { editView.addDeleteListener(() -> { - FacadeProvider.getTaskFacade().deleteTask(newDto); + FacadeProvider.getTaskFacade().deleteTask(task); UI.getCurrent().removeWindow(popupWindow); callback.run(); }, I18nProperties.getString(Strings.entityTask)); @@ -146,18 +148,18 @@ public void edit(TaskIndexDto dto, Runnable callback, boolean editedFromTaskGrid // Initialize 'Archive' button if (UserProvider.getCurrent().hasUserRight(UserRight.TASK_ARCHIVE)) { - boolean archived = FacadeProvider.getTaskFacade().isArchived(dto.getUuid()); + boolean archived = FacadeProvider.getTaskFacade().isArchived(task.getUuid()); Button archiveButton = ButtonHelper.createButton( ArchivingController.ARCHIVE_DEARCHIVE_BUTTON_ID, I18nProperties.getCaption(archived ? Captions.actionDearchiveCoreEntity : Captions.actionArchiveCoreEntity), e -> { if (editView.isDirty()) { - DirtyCheckPopup.show(editView, () -> archiveOrDearchive(newDto, !archived, () -> { + DirtyCheckPopup.show(editView, () -> archiveOrDearchive(task, !archived, () -> { popupWindow.close(); callback.run(); })); } else { - archiveOrDearchive(newDto, !archived, () -> { + archiveOrDearchive(task, !archived, () -> { popupWindow.close(); callback.run(); }); @@ -168,6 +170,8 @@ public void edit(TaskIndexDto dto, Runnable callback, boolean editedFromTaskGrid editView.getButtonsPanel().addComponentAsFirst(archiveButton); editView.getButtonsPanel().setComponentAlignment(archiveButton, Alignment.BOTTOM_LEFT); } + + editView.setEditable(isEditingAllowed, ArchivingController.ARCHIVE_DEARCHIVE_BUTTON_ID); } private TaskDto createNewTask(TaskContext context, ReferenceDto entityRef) { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskGrid.java index def3be4171a..ae44a6b522b 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskGrid.java @@ -163,7 +163,7 @@ public TaskGrid(TaskCriteria criteria) { return UiFieldAccessCheckers.getDefault(!isInJurisdiction).hasRight(); })); - addItemClickListener(new ShowDetailsListener<>(TaskIndexDto.CONTEXT_REFERENCE, false, e -> navigateToData(e))); + addItemClickListener(new ShowDetailsListener<>(TaskIndexDto.CONTEXT_REFERENCE, false, this::navigateToData)); } public void reload() { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryDataView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryDataView.java index 5447de4a22c..604e1660eb8 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryDataView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryDataView.java @@ -93,7 +93,7 @@ protected void initView(String params) { UserRight.TRAVEL_ENTRY_EDIT, travelEntryDto.isPseudonymized(), editAllowed, - editAllowed); + EditPermissionType.WITHOUT_OWNERSHIP.equals(travelEntryEditAllowed)); layout.addSidePanelComponent(new SideComponentLayout(documentList), DOCUMENTS_LOC); } From c92e2679e85cae50019d80acec87408163fe0975 Mon Sep 17 00:00:00 2001 From: Christopher Riedel Date: Wed, 4 Jan 2023 09:19:43 +0100 Subject: [PATCH 058/166] fixed #11120 (#11250) Co-authored-by: Carina Paul --- .../main/java/de/symeda/sormas/ui/caze/CaseController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java index 0f9e4e4598e..c21ad8d5c6c 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java @@ -1630,8 +1630,8 @@ public void deleteAllSelectedItems(Collection selectedRo DeletableUtils.showDeleteWithReasonPopup( String.format( I18nProperties.getString(Strings.confirmationDeleteCases), - selectedRows.size(), - getDeleteConfirmationDetails(selectedRows.stream().map(CaseIndexDto::getUuid).collect(Collectors.toList()))), + selectedRows.size()) + "
" + + getDeleteConfirmationDetails(selectedRows.stream().map(CaseIndexDto::getUuid).collect(Collectors.toList())), (deleteDetails) -> { int countNotDeletedCases = 0; StringBuilder nonDeletableCases = new StringBuilder(); From 907b4518a2bcec44da418be4fd9cd725eca83f3b Mon Sep 17 00:00:00 2001 From: Frank Hautpmann Date: Wed, 4 Jan 2023 09:50:10 +0100 Subject: [PATCH 059/166] New Crowdin updates (#11252) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * New translations enum.properties (German, Switzerland) * New translations descriptions.properties (German, Switzerland) * New translations validations.properties (German, Switzerland) * New translations captions.properties (German) * New translations captions.properties (Spanish, Cuba) * New translations strings.properties (Spanish, Cuba) * New translations strings.properties (German, Switzerland) * New translations captions.properties (German, Switzerland) * New translations strings.properties (German, Switzerland) * New translations enum.properties (French) * New translations strings.properties (Romanian) * New translations strings.properties (French) * New translations strings.properties (Spanish) * New translations strings.properties (Arabic) * New translations strings.properties (Czech) * New translations strings.properties (German) * New translations strings.properties (Finnish) * New translations strings.properties (Italian) * New translations strings.properties (Japanese) * New translations strings.properties (Dutch) * New translations strings.properties (Norwegian) * New translations strings.properties (Polish) * New translations strings.properties (Portuguese) * New translations strings.properties (Russian) * New translations strings.properties (Swedish) * New translations strings.properties (Turkish) * New translations strings.properties (Ukrainian) * New translations strings.properties (Chinese Simplified) * New translations strings.properties (Urdu (Pakistan)) * New translations strings.properties (Spanish, Ecuador) * New translations strings.properties (Croatian) * New translations strings.properties (Hindi) * New translations strings.properties (Filipino) * New translations strings.properties (Fijian) * New translations strings.properties (Swahili) * New translations strings.properties (Nepali) * New translations strings.properties (French, Switzerland) * New translations strings.properties (Italian, Switzerland) * New translations strings.properties (Dari) * New translations strings.properties (Pashto) * New translations strings.properties (Spanish, Cuba) * New translations strings.properties (English, Afghanistan) * New translations strings.properties (English, Nigeria) * New translations strings.properties (English, Ghana) * New translations enum.properties (Romanian) * New translations enum.properties (Spanish) * New translations enum.properties (Arabic) * New translations enum.properties (Czech) * New translations enum.properties (German) * New translations enum.properties (Finnish) * New translations enum.properties (Italian) * New translations enum.properties (Japanese) * New translations enum.properties (Dutch) * New translations enum.properties (Norwegian) * New translations enum.properties (Polish) * New translations enum.properties (Portuguese) * New translations enum.properties (Russian) * New translations enum.properties (Swedish) * New translations enum.properties (Turkish) * New translations enum.properties (Ukrainian) * New translations enum.properties (Chinese Simplified) * New translations enum.properties (Urdu (Pakistan)) * New translations enum.properties (Spanish, Ecuador) * New translations enum.properties (Croatian) * New translations enum.properties (Hindi) * New translations enum.properties (Filipino) * New translations enum.properties (Fijian) * New translations enum.properties (Swahili) * New translations enum.properties (German, Switzerland) * New translations enum.properties (Nepali) * New translations enum.properties (French, Switzerland) * New translations enum.properties (Italian, Switzerland) * New translations enum.properties (Dari) * New translations enum.properties (Pashto) * New translations enum.properties (Spanish, Cuba) * New translations enum.properties (English, Afghanistan) * New translations enum.properties (English, Nigeria) * New translations enum.properties (English, Ghana) * New translations enum.properties (French) * New translations captions.properties (French) * New translations strings.properties (Spanish, Cuba) * New translations enum.properties (Spanish, Cuba) * New translations captions.properties (Urdu (Pakistan)) * New translations strings.properties (Czech) * New translations strings.properties (Urdu (Pakistan)) * New translations enum.properties (Czech) * New translations enum.properties (Urdu (Pakistan)) * New translations descriptions.properties (Urdu (Pakistan)) * New translations validations.properties (Urdu (Pakistan)) * New translations enum.properties (French) * New translations enum.properties (Romanian) * New translations enum.properties (Spanish) * New translations enum.properties (Arabic) * New translations enum.properties (Czech) * New translations enum.properties (German) * New translations enum.properties (Finnish) * New translations enum.properties (Italian) * New translations enum.properties (Japanese) * New translations enum.properties (Dutch) * New translations enum.properties (Norwegian) * New translations enum.properties (Polish) * New translations enum.properties (Portuguese) * New translations enum.properties (Russian) * New translations enum.properties (Swedish) * New translations enum.properties (Turkish) * New translations enum.properties (Ukrainian) * New translations enum.properties (Chinese Simplified) * New translations enum.properties (Urdu (Pakistan)) * New translations enum.properties (Spanish, Ecuador) * New translations enum.properties (Croatian) * New translations enum.properties (Hindi) * New translations enum.properties (Filipino) * New translations enum.properties (Fijian) * New translations enum.properties (Swahili) * New translations enum.properties (German, Switzerland) * New translations enum.properties (Nepali) * New translations enum.properties (French, Switzerland) * New translations enum.properties (Italian, Switzerland) * New translations enum.properties (Dari) * New translations enum.properties (Pashto) * New translations enum.properties (Spanish, Cuba) * New translations enum.properties (English, Afghanistan) * New translations enum.properties (English, Nigeria) * New translations enum.properties (English, Ghana) * New translations enum.properties (Spanish, Cuba) * New translations strings.properties (German, Switzerland) * New translations strings.properties (Romanian) * New translations strings.properties (French) * New translations strings.properties (Spanish) * New translations strings.properties (Arabic) * New translations strings.properties (Czech) * New translations strings.properties (German) * New translations strings.properties (Finnish) * New translations strings.properties (Italian) * New translations strings.properties (Japanese) * New translations strings.properties (Dutch) * New translations strings.properties (Norwegian) * New translations strings.properties (Polish) * New translations strings.properties (Portuguese) * New translations strings.properties (Russian) * New translations strings.properties (Swedish) * New translations strings.properties (Turkish) * New translations strings.properties (Ukrainian) * New translations strings.properties (Chinese Simplified) * New translations strings.properties (Urdu (Pakistan)) * New translations strings.properties (Spanish, Ecuador) * New translations strings.properties (Croatian) * New translations strings.properties (Hindi) * New translations strings.properties (Filipino) * New translations strings.properties (Fijian) * New translations strings.properties (Swahili) * New translations strings.properties (Nepali) * New translations strings.properties (French, Switzerland) * New translations strings.properties (Italian, Switzerland) * New translations strings.properties (Dari) * New translations strings.properties (Pashto) * New translations strings.properties (Spanish, Cuba) * New translations strings.properties (English, Afghanistan) * New translations strings.properties (English, Nigeria) * New translations strings.properties (English, Ghana) * New translations strings.properties (German, Switzerland) * New translations strings.properties (Romanian) * New translations strings.properties (French) * New translations strings.properties (Spanish) * New translations strings.properties (Arabic) * New translations strings.properties (Czech) * New translations strings.properties (German) * New translations strings.properties (Finnish) * New translations strings.properties (Italian) * New translations strings.properties (Japanese) * New translations strings.properties (Dutch) * New translations strings.properties (Norwegian) * New translations strings.properties (Polish) * New translations strings.properties (Portuguese) * New translations strings.properties (Russian) * New translations strings.properties (Swedish) * New translations strings.properties (Turkish) * New translations strings.properties (Ukrainian) * New translations strings.properties (Chinese Simplified) * New translations strings.properties (Urdu (Pakistan)) * New translations strings.properties (Spanish, Ecuador) * New translations strings.properties (Croatian) * New translations strings.properties (Hindi) * New translations strings.properties (Filipino) * New translations strings.properties (Fijian) * New translations strings.properties (Swahili) * New translations strings.properties (Nepali) * New translations strings.properties (French, Switzerland) * New translations strings.properties (Italian, Switzerland) * New translations strings.properties (Dari) * New translations strings.properties (Pashto) * New translations strings.properties (Spanish, Cuba) * New translations strings.properties (English, Afghanistan) * New translations strings.properties (English, Nigeria) * New translations strings.properties (English, Ghana) * New translations strings.properties (German, Switzerland) * New translations enum.properties (French) * New translations strings.properties (Czech) * New translations strings.properties (German) * New translations strings.properties (Urdu (Pakistan)) * New translations strings.properties (Spanish, Cuba) * New translations enum.properties (German) * New translations enum.properties (Urdu (Pakistan)) * New translations enum.properties (German, Switzerland) * New translations enum.properties (French) * New translations strings.properties (French) * New translations strings.properties (German, Switzerland) * New translations strings.properties (Romanian) * New translations strings.properties (French) * New translations strings.properties (Spanish) * New translations strings.properties (Arabic) * New translations strings.properties (Czech) * New translations strings.properties (German) * New translations strings.properties (Finnish) * New translations strings.properties (Italian) * New translations strings.properties (Japanese) * New translations strings.properties (Dutch) * New translations strings.properties (Norwegian) * New translations strings.properties (Polish) * New translations strings.properties (Portuguese) * New translations strings.properties (Russian) * New translations strings.properties (Swedish) * New translations strings.properties (Turkish) * New translations strings.properties (Ukrainian) * New translations strings.properties (Chinese Simplified) * New translations strings.properties (Urdu (Pakistan)) * New translations strings.properties (Spanish, Ecuador) * New translations strings.properties (Croatian) * New translations strings.properties (Hindi) * New translations strings.properties (Filipino) * New translations strings.properties (Fijian) * New translations strings.properties (Swahili) * New translations strings.properties (Nepali) * New translations strings.properties (French, Switzerland) * New translations strings.properties (Italian, Switzerland) * New translations strings.properties (Dari) * New translations strings.properties (Pashto) * New translations strings.properties (Spanish, Cuba) * New translations strings.properties (English, Afghanistan) * New translations strings.properties (English, Nigeria) * New translations strings.properties (English, Ghana) * New translations strings.properties (German) * New translations strings.properties (Urdu (Pakistan)) * New translations strings.properties (Spanish, Cuba) * New translations strings.properties (German, Switzerland) Co-authored-by: Maté Strysewske Co-authored-by: StefanKock --- sormas-api/src/main/resources/strings_ar-SA.properties | 2 ++ sormas-api/src/main/resources/strings_cs-CZ.properties | 2 ++ sormas-api/src/main/resources/strings_de-CH.properties | 1 + sormas-api/src/main/resources/strings_de-DE.properties | 1 + sormas-api/src/main/resources/strings_en-AF.properties | 2 ++ sormas-api/src/main/resources/strings_en-GH.properties | 2 ++ sormas-api/src/main/resources/strings_en-NG.properties | 2 ++ sormas-api/src/main/resources/strings_es-CU.properties | 2 ++ sormas-api/src/main/resources/strings_es-EC.properties | 2 ++ sormas-api/src/main/resources/strings_es-ES.properties | 2 ++ sormas-api/src/main/resources/strings_fa-AF.properties | 2 ++ sormas-api/src/main/resources/strings_fi-FI.properties | 2 ++ sormas-api/src/main/resources/strings_fil-PH.properties | 2 ++ sormas-api/src/main/resources/strings_fj-FJ.properties | 2 ++ sormas-api/src/main/resources/strings_fr-CH.properties | 2 ++ sormas-api/src/main/resources/strings_fr-FR.properties | 2 ++ sormas-api/src/main/resources/strings_hi-IN.properties | 2 ++ sormas-api/src/main/resources/strings_hr-HR.properties | 2 ++ sormas-api/src/main/resources/strings_it-CH.properties | 2 ++ sormas-api/src/main/resources/strings_it-IT.properties | 2 ++ sormas-api/src/main/resources/strings_ja-JP.properties | 2 ++ sormas-api/src/main/resources/strings_ne-NP.properties | 2 ++ sormas-api/src/main/resources/strings_nl-NL.properties | 2 ++ sormas-api/src/main/resources/strings_no-NO.properties | 2 ++ sormas-api/src/main/resources/strings_pl-PL.properties | 2 ++ sormas-api/src/main/resources/strings_ps-AF.properties | 2 ++ sormas-api/src/main/resources/strings_pt-PT.properties | 2 ++ sormas-api/src/main/resources/strings_ro-RO.properties | 2 ++ sormas-api/src/main/resources/strings_ru-RU.properties | 2 ++ sormas-api/src/main/resources/strings_sv-SE.properties | 2 ++ sormas-api/src/main/resources/strings_sw-KE.properties | 2 ++ sormas-api/src/main/resources/strings_tr-TR.properties | 2 ++ sormas-api/src/main/resources/strings_uk-UA.properties | 2 ++ sormas-api/src/main/resources/strings_ur-PK.properties | 1 + sormas-api/src/main/resources/strings_zh-CN.properties | 2 ++ 35 files changed, 67 insertions(+) diff --git a/sormas-api/src/main/resources/strings_ar-SA.properties b/sormas-api/src/main/resources/strings_ar-SA.properties index 7717fec1c94..6ec666c5a95 100644 --- a/sormas-api/src/main/resources/strings_ar-SA.properties +++ b/sormas-api/src/main/resources/strings_ar-SA.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 2c7bb2a9da5..546fe1b464e 100644 --- a/sormas-api/src/main/resources/strings_cs-CZ.properties +++ b/sormas-api/src/main/resources/strings_cs-CZ.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = Existuje čekající požadavek na sdíle messageCannotMergeMoreThanTwoPersons = Pro sloučení musíte vybrat dvě osoby\! messageAutomaticDeletionStarted = Automatické smazání bylo zahájeno a bude provedeno na pozadí. Vezměte prosím na vědomí, že v závislosti na množství dat, která jsou odstraněna, může tento proces nějakou dobu trvat. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 04f09e53d4c..9e95bbd20f3 100644 --- a/sormas-api/src/main/resources/strings_de-CH.properties +++ b/sormas-api/src/main/resources/strings_de-CH.properties @@ -1286,6 +1286,7 @@ messageDeleteWithPendingShareRequest = Es gibt eine ausstehende Freigabeanfrage. messageCannotMergeMoreThanTwoPersons = Sie müssen zwei Personen zum Zusammenführen auswählen\! messageAutomaticDeletionStarted = Automatisches Löschen wurde gestartet und wird im Hintergrund ausgeführt. Bitte beachten Sie, dass dieser Prozess je nach Anzahl der zu löschenden Daten einige Zeit in Anspruch nehmen kann. messageUserRoleUnusableForLogin = Benutzer mit nur dieser Rolle können sich nicht anmelden, da die Rolle weder Zugang Sormas UI noch Zugang Sormas REST Rechte hat +messageUserRoleHasNoRights = Diese Benutzerrolle hat keine Rechte. Bitte wählen Sie mindestens ein Recht aus. # 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 e563edab1f8..a730ecdbadd 100644 --- a/sormas-api/src/main/resources/strings_de-DE.properties +++ b/sormas-api/src/main/resources/strings_de-DE.properties @@ -1286,6 +1286,7 @@ messageDeleteWithPendingShareRequest = Es gibt eine ausstehende Anfrage zur Übe messageCannotMergeMoreThanTwoPersons = Sie müssen zwei Personen zum Zusammenführen auswählen\! messageAutomaticDeletionStarted = Automatisches Löschen wurde gestartet und wird im Hintergrund ausgeführt. Bitte beachten Sie, dass dieser Prozess je nach Anzahl der zu löschenden Daten einige Zeit in Anspruch nehmen kann. messageUserRoleUnusableForLogin = Benutzer mit nur dieser Rolle können sich nicht anmelden, da die Rolle weder Zugang Sormas UI noch Zugang Sormas REST Rechte hat +messageUserRoleHasNoRights = Diese Benutzerrolle hat keine Rechte. Bitte wählen Sie mindestens ein Recht aus. # 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 9b694090d9e..046cacfa03d 100644 --- a/sormas-api/src/main/resources/strings_en-AF.properties +++ b/sormas-api/src/main/resources/strings_en-AF.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 fa9858b8c20..0cf4295d32c 100644 --- a/sormas-api/src/main/resources/strings_en-GH.properties +++ b/sormas-api/src/main/resources/strings_en-GH.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 8a1ca571153..25a204af54f 100644 --- a/sormas-api/src/main/resources/strings_en-NG.properties +++ b/sormas-api/src/main/resources/strings_en-NG.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 5bc53239f0e..df0fe37a4f6 100644 --- a/sormas-api/src/main/resources/strings_es-CU.properties +++ b/sormas-api/src/main/resources/strings_es-CU.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = Hay una solicitud de compartición pendie messageCannotMergeMoreThanTwoPersons = ¡Debe seleccionar dos personas para combinar\! messageAutomaticDeletionStarted = La eliminación automática se ha iniciado y se ejecutará en segundo plano. Tenga en cuenta que, dependiendo de la cantidad de datos que se eliminen, este proceso puede tardar algún tiempo. messageUserRoleUnusableForLogin = Los usuarios que sólo tengan este rol no podrán iniciar sesión porque el rol no tiene derecho de Acceso a Sormas UI ni derecho de Acceso a Sormas REST +messageUserRoleHasNoRights = Este rol de usuario no tiene derechos. Por favor, seleccione al menos un derecho. + # Notifications notificationCaseClassificationChanged = La clasificación del caso %s se cambió a %s. diff --git a/sormas-api/src/main/resources/strings_es-EC.properties b/sormas-api/src/main/resources/strings_es-EC.properties index 7d891d3a5bc..23a062b044e 100644 --- a/sormas-api/src/main/resources/strings_es-EC.properties +++ b/sormas-api/src/main/resources/strings_es-EC.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # Notifications notificationCaseClassificationChanged = La clasificación del caso %s ha sido cambiado 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 f9dac827068..53f66cf2b09 100644 --- a/sormas-api/src/main/resources/strings_es-ES.properties +++ b/sormas-api/src/main/resources/strings_es-ES.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 f9dac827068..53f66cf2b09 100644 --- a/sormas-api/src/main/resources/strings_fa-AF.properties +++ b/sormas-api/src/main/resources/strings_fa-AF.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 1e3e665034d..6ca848ff5b8 100644 --- a/sormas-api/src/main/resources/strings_fi-FI.properties +++ b/sormas-api/src/main/resources/strings_fi-FI.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 f9dac827068..53f66cf2b09 100644 --- a/sormas-api/src/main/resources/strings_fil-PH.properties +++ b/sormas-api/src/main/resources/strings_fil-PH.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 f9dac827068..53f66cf2b09 100644 --- a/sormas-api/src/main/resources/strings_fj-FJ.properties +++ b/sormas-api/src/main/resources/strings_fj-FJ.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 a6111ec0f7d..116aa285e9c 100644 --- a/sormas-api/src/main/resources/strings_fr-CH.properties +++ b/sormas-api/src/main/resources/strings_fr-CH.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 827ef059fc8..116c1a87ef2 100644 --- a/sormas-api/src/main/resources/strings_fr-FR.properties +++ b/sormas-api/src/main/resources/strings_fr-FR.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 f9dac827068..53f66cf2b09 100644 --- a/sormas-api/src/main/resources/strings_hi-IN.properties +++ b/sormas-api/src/main/resources/strings_hi-IN.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 f9dac827068..53f66cf2b09 100644 --- a/sormas-api/src/main/resources/strings_hr-HR.properties +++ b/sormas-api/src/main/resources/strings_hr-HR.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 57538458b8a..aa3d0c326ab 100644 --- a/sormas-api/src/main/resources/strings_it-CH.properties +++ b/sormas-api/src/main/resources/strings_it-CH.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 67ac96f486f..5d7a5d13756 100644 --- a/sormas-api/src/main/resources/strings_it-IT.properties +++ b/sormas-api/src/main/resources/strings_it-IT.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 f9dac827068..53f66cf2b09 100644 --- a/sormas-api/src/main/resources/strings_ja-JP.properties +++ b/sormas-api/src/main/resources/strings_ja-JP.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 7717fec1c94..6ec666c5a95 100644 --- a/sormas-api/src/main/resources/strings_ne-NP.properties +++ b/sormas-api/src/main/resources/strings_ne-NP.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 f9dac827068..53f66cf2b09 100644 --- a/sormas-api/src/main/resources/strings_nl-NL.properties +++ b/sormas-api/src/main/resources/strings_nl-NL.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 f9dac827068..53f66cf2b09 100644 --- a/sormas-api/src/main/resources/strings_no-NO.properties +++ b/sormas-api/src/main/resources/strings_no-NO.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 f9dac827068..53f66cf2b09 100644 --- a/sormas-api/src/main/resources/strings_pl-PL.properties +++ b/sormas-api/src/main/resources/strings_pl-PL.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 fb0107da1ba..f4420f16e5c 100644 --- a/sormas-api/src/main/resources/strings_ps-AF.properties +++ b/sormas-api/src/main/resources/strings_ps-AF.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 f9dac827068..53f66cf2b09 100644 --- a/sormas-api/src/main/resources/strings_pt-PT.properties +++ b/sormas-api/src/main/resources/strings_pt-PT.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 f9dac827068..53f66cf2b09 100644 --- a/sormas-api/src/main/resources/strings_ro-RO.properties +++ b/sormas-api/src/main/resources/strings_ro-RO.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 11a7ed70331..f770626c0c3 100644 --- a/sormas-api/src/main/resources/strings_ru-RU.properties +++ b/sormas-api/src/main/resources/strings_ru-RU.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 f9dac827068..53f66cf2b09 100644 --- a/sormas-api/src/main/resources/strings_sv-SE.properties +++ b/sormas-api/src/main/resources/strings_sv-SE.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 f9dac827068..53f66cf2b09 100644 --- a/sormas-api/src/main/resources/strings_sw-KE.properties +++ b/sormas-api/src/main/resources/strings_sw-KE.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 f9dac827068..53f66cf2b09 100644 --- a/sormas-api/src/main/resources/strings_tr-TR.properties +++ b/sormas-api/src/main/resources/strings_tr-TR.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 f9dac827068..53f66cf2b09 100644 --- a/sormas-api/src/main/resources/strings_uk-UA.properties +++ b/sormas-api/src/main/resources/strings_uk-UA.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # 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 5a34f2a12b9..394e939b16b 100644 --- a/sormas-api/src/main/resources/strings_ur-PK.properties +++ b/sormas-api/src/main/resources/strings_ur-PK.properties @@ -1286,6 +1286,7 @@ messageDeleteWithPendingShareRequest = شیئر کی درخواست زیر ال messageCannotMergeMoreThanTwoPersons = آپ کو انضمام کے لیے دو افراد کو منتخب کرنے کی ضرورت ہے\! messageAutomaticDeletionStarted = خودکار مٹانا شروع کر دیا گیا ہے اور اسے پس منظر میں عمل میں لایا جائے گا۔ براہ کرم نوٹ کریں کہ مٹنے والے ڈیٹا کی مقدار پر منحصر ہے، اس عمل میں کچھ وقت لگ سکتا ہے۔ messageUserRoleUnusableForLogin = صرف اس کردار کے حامل صارفین لاگ ان نہیں کر پائیں گے کیونکہ اس رول میں Access Sormas UI نہیں ہے اور نہ ہی Sormas REST تک رسائی حاصل ہے۔ +messageUserRoleHasNoRights = اس صارف کے کردار کا کوئی حق نہیں ہے۔ براہ کرم کم از کم ایک صحیح منتخب کریں۔ # 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 4ab3a8f756f..44552f5ab57 100644 --- a/sormas-api/src/main/resources/strings_zh-CN.properties +++ b/sormas-api/src/main/resources/strings_zh-CN.properties @@ -1286,6 +1286,8 @@ messageDeleteWithPendingShareRequest = There is a pending share request. With a messageCannotMergeMoreThanTwoPersons = You need to select two persons for merge\! messageAutomaticDeletionStarted = Automatic deletion has been started and will be executed in the background. Please note that, depending on the amount of data that is deleted, this process can take some time. messageUserRoleUnusableForLogin = Users with only this role will not be able to login because the role does not have Access Sormas UI nor Access Sormas REST right +messageUserRoleHasNoRights = This user role has no rights. Please select at least one right. + # Notifications notificationCaseClassificationChanged = The classification of case %s has changed to %s. From 557964b80ea08bea6a4c5462e47958a582681f57 Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Wed, 4 Jan 2023 11:31:10 +0100 Subject: [PATCH 060/166] no of countries xpath change --- .../pages/application/configuration/CountriesTabPage.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java index 89bbe4adaa3..3b6c796cf98 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java @@ -36,8 +36,8 @@ public class CountriesTabPage { public static final By SUBCONTINENT_TABLE_VALUE = By.xpath("//table//tbody//tr[1]/td[4]"); public static final By COUNTRY_GRID_RESULTS_ROWS = By.cssSelector("[role=rowgroup] tr a"); public static final By NUMBER_OF_COUNTRIES = - By.xpath( - "//div[@class='v-label v-widget bold v-label-bold vspace-top-none v-label-vspace-top-none align-right v-label-align-right v-label-undef-w']"); + By.xpath( + "//div[@class='v-label v-widget v-label-undef-w bold v-label-bold vspace-top-none v-label-vspace-top-none align-right v-label-align-right']"); public static final By COUNTRIES_TABLE_DATA = By.tagName("td"); public static final By COUNTRIES_TABLE_ROW = By.cssSelector("div.v-grid-tablewrapper tbody tr"); public static final By COUNTRIES_NAME_TABLE_ROW = From 0608a506850d8f51d5c2354a202dbe3a89c2139d Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Wed, 4 Jan 2023 14:10:28 +0100 Subject: [PATCH 061/166] rerunAttempts=4 --- .../java/org/sormas/e2etests/runner/CucumberTestRunner.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/runner/CucumberTestRunner.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/runner/CucumberTestRunner.java index ca42a03a16a..52324d2bc3f 100755 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/runner/CucumberTestRunner.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/runner/CucumberTestRunner.java @@ -29,7 +29,7 @@ runLevel = CourgetteRunLevel.SCENARIO, showTestOutput = true, rerunFailedScenarios = true, - rerunAttempts = 3, + rerunAttempts = 4, cucumberOptions = @CucumberOptions( features = "src/test/resources/features", From 63d8b009c24500193d09f4c835a8b81269d617ca Mon Sep 17 00:00:00 2001 From: Adrian Dinu Date: Wed, 4 Jan 2023 16:00:47 +0200 Subject: [PATCH 062/166] #10033 show message only when no rights (#11261) --- .../de/symeda/sormas/ui/user/UserRoleController.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserRoleController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserRoleController.java index 80c5847a749..3e5aafaec85 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserRoleController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserRoleController.java @@ -65,11 +65,12 @@ public CommitDiscardWrapperComponent getUserRoleCreateCompon if (!createForm.getFieldGroup().isModified()) { UserRoleDto dto = createForm.getValue(); FacadeProvider.getUserRoleFacade().saveUserRole(dto); - - Notification.show( - I18nProperties.getString(Strings.messageUserRoleSaved), - I18nProperties.getString(Strings.messageUserRoleHasNoRights), - Notification.Type.WARNING_MESSAGE); + if (dto.getUserRights().size() == 0) { + Notification.show( + I18nProperties.getString(Strings.messageUserRoleSaved), + I18nProperties.getString(Strings.messageUserRoleHasNoRights), + Notification.Type.WARNING_MESSAGE); + } editData(dto.getUuid()); } }); From 3b220314003833c97f2e3f8fc8ba6447a854a64f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=A9=20Strysewske?= Date: Wed, 4 Jan 2023 15:15:32 +0100 Subject: [PATCH 063/166] #7305 - Refactoring, moved deletion to mobile app --- .../app/backend/common/AbstractAdoDao.java | 28 +++++ .../feature/FeatureConfigurationDao.java | 50 +++++++- .../sormas/app/rest/SynchronizeDataAsync.java | 84 ++++++++----- .../sormas/backend/action/ActionService.java | 25 +--- .../backend/campaign/CampaignService.java | 17 +-- .../data/CampaignFormDataService.java | 15 --- .../CampaignDiagramDefinitionService.java | 15 --- .../form/CampaignFormMetaService.java | 15 --- .../sormas/backend/caze/CaseService.java | 63 +++------- .../SurveillanceReportService.java | 15 --- .../clinicalcourse/ClinicalVisitService.java | 25 ---- .../AbstractInfrastructureAdoService.java | 16 --- ...oServiceWithUserFilterAndJurisdiction.java | 65 +++------- .../EmptyLimitedChangeDateFilterProvider.java | 18 +++ .../LimitedChangeDateFilterProvider.java | 33 +++++ .../backend/contact/ContactService.java | 52 ++------ .../CustomizableEnumValueService.java | 14 --- .../disease/DiseaseConfigurationService.java | 14 --- .../backend/document/DocumentService.java | 15 --- .../backend/event/EventGroupService.java | 15 --- .../event/EventParticipantService.java | 43 +------ .../sormas/backend/event/EventService.java | 42 ++----- .../ExternalMessageService.java | 15 --- .../feature/FeatureConfigurationService.java | 15 --- .../DirectoryImmunizationService.java | 15 --- .../immunization/ImmunizationService.java | 12 +- .../infrastructure/PopulationDataService.java | 26 +--- .../backend/outbreak/OutbreakService.java | 15 --- .../sormas/backend/person/PersonService.java | 21 ---- .../report/AggregateReportService.java | 15 --- .../report/WeeklyReportEntryService.java | 15 --- .../backend/report/WeeklyReportService.java | 15 --- .../backend/sample/AdditionalTestService.java | 25 +--- .../backend/sample/PathogenTestService.java | 23 ---- .../sormas/backend/sample/SampleService.java | 83 +++--------- .../share/ExternalShareInfoService.java | 15 --- .../SormasToSormasOriginInfoService.java | 15 --- .../SormasToSormasShareRequestService.java | 15 --- .../outgoing/ShareRequestInfoService.java | 15 --- .../SormasToSormasShareInfoService.java | 16 --- .../sormas/backend/task/TaskService.java | 119 +++++------------- .../backend/therapy/PrescriptionService.java | 26 ---- .../backend/therapy/TreatmentService.java | 26 +--- .../services/BaseTravelEntryService.java | 19 +-- .../sormas/backend/user/UserRoleService.java | 15 --- .../sormas/backend/user/UserService.java | 16 --- .../vaccination/VaccinationService.java | 25 +--- .../sormas/backend/visit/VisitService.java | 22 ---- 48 files changed, 305 insertions(+), 1013 deletions(-) create mode 100644 sormas-backend/src/main/java/de/symeda/sormas/backend/common/EmptyLimitedChangeDateFilterProvider.java create mode 100644 sormas-backend/src/main/java/de/symeda/sormas/backend/common/LimitedChangeDateFilterProvider.java diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AbstractAdoDao.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AbstractAdoDao.java index beba427db5b..a4122be3668 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AbstractAdoDao.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AbstractAdoDao.java @@ -20,6 +20,7 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.Iterator; import java.util.List; @@ -42,6 +43,8 @@ import android.util.Log; import de.symeda.sormas.api.ReferenceDto; +import de.symeda.sormas.api.feature.FeatureType; +import de.symeda.sormas.api.feature.FeatureTypeProperty; import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.utils.DataHelper; import de.symeda.sormas.api.utils.DateHelper; @@ -284,6 +287,31 @@ public List queryForModified() { return queryForEq(ADO.MODIFIED, true); } + public List queryForObsolete() { + + if (DatabaseHelper.getFeatureConfigurationDao().isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION)) { + Integer maxChangeDatePeriod = DatabaseHelper.getFeatureConfigurationDao() + .getIntegerPropertyValue(FeatureType.LIMITED_SYNCHRONIZATION, FeatureTypeProperty.MAX_CHANGE_DATE_PERIOD); + if (maxChangeDatePeriod != null && maxChangeDatePeriod >= 0) { + Date maxChangeDate = DateHelper.getStartOfDay(DateHelper.subtractDays(new Date(), maxChangeDatePeriod)); + try { + QueryBuilder builder = queryBuilder(); + Where where = builder.where(); + where.and( + where.isNotNull(AbstractDomainObject.CHANGE_DATE), + where.eq(ADO.MODIFIED, false), + where.lt(AbstractDomainObject.CHANGE_DATE, maxChangeDate), + where.lt(AbstractDomainObject.LOCAL_CHANGE_DATE, maxChangeDate)); + return builder.query(); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + } + + return Collections.emptyList(); + } + public ADO getByReferenceDto(ReferenceDto dto) { if (dto == null) { return null; diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/feature/FeatureConfigurationDao.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/feature/FeatureConfigurationDao.java index 791c5c4e351..baa2f0e1a3e 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/feature/FeatureConfigurationDao.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/feature/FeatureConfigurationDao.java @@ -1,6 +1,10 @@ package de.symeda.sormas.app.backend.feature; -import android.util.Log; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; import com.j256.ormlite.dao.Dao; import com.j256.ormlite.dao.GenericRawResults; @@ -8,11 +12,7 @@ import com.j256.ormlite.stmt.QueryBuilder; import com.j256.ormlite.stmt.Where; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; +import android.util.Log; import de.symeda.sormas.api.Disease; import de.symeda.sormas.api.feature.FeatureType; @@ -89,6 +89,44 @@ public boolean isFeatureEnabled(FeatureType featureType) { } } + public Integer getIntegerPropertyValue(FeatureType featureType, FeatureTypeProperty property) { + if (!featureType.getSupportedProperties().contains(property)) { + throw new IllegalArgumentException("Feature type " + featureType + " does not support property " + property + "."); + } + + if (!Integer.class.isAssignableFrom(property.getReturnType())) { + throw new IllegalArgumentException( + "Feature type property " + property + " does not have specified return type " + Integer.class.getSimpleName() + "."); + } + + Map propertyObjectMap; + try { + QueryBuilder builder = queryBuilder(); + Where where = builder.where(); + where.eq(FeatureConfiguration.FEATURE_TYPE, featureType); + builder.selectColumns(FeatureConfiguration.PROPERTIES); + + FeatureConfiguration featureConfiguration = (FeatureConfiguration) builder.queryForFirst(); + + if (featureConfiguration != null && featureConfiguration.getPropertiesJson() != null) { + propertyObjectMap = featureConfiguration.getPropertiesMap(); + } else { + return (Integer) featureType.getSupportedPropertyDefaults().get(property); + } + + } catch (SQLException e) { + Log.e(getTableName(), "Could not perform getIntegerPropertyValue"); + throw new RuntimeException(e); + } + + boolean result; + if (propertyObjectMap != null && propertyObjectMap.containsKey(property)) { + return (Integer) propertyObjectMap.get(property); + } else { + return null; + } + } + public boolean isPropertyValueTrue(FeatureType featureType, FeatureTypeProperty property) { if (!featureType.getSupportedProperties().contains(property)) { throw new IllegalArgumentException("Feature type " + featureType + " does not support property " + property + "."); diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/SynchronizeDataAsync.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/SynchronizeDataAsync.java index 0f5c1f78210..02a2f799b2f 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/SynchronizeDataAsync.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/SynchronizeDataAsync.java @@ -60,6 +60,7 @@ import de.symeda.sormas.app.backend.campaign.CampaignDtoHelper; import de.symeda.sormas.app.backend.campaign.data.CampaignFormDataDtoHelper; import de.symeda.sormas.app.backend.campaign.form.CampaignFormMetaDtoHelper; +import de.symeda.sormas.app.backend.caze.Case; import de.symeda.sormas.app.backend.caze.CaseDtoHelper; import de.symeda.sormas.app.backend.classification.DiseaseClassificationDtoHelper; import de.symeda.sormas.app.backend.clinicalcourse.ClinicalVisitDtoHelper; @@ -68,13 +69,16 @@ import de.symeda.sormas.app.backend.common.DtoFeatureConfigHelper; import de.symeda.sormas.app.backend.common.DtoUserRightsHelper; import de.symeda.sormas.app.backend.config.ConfigProvider; +import de.symeda.sormas.app.backend.contact.Contact; import de.symeda.sormas.app.backend.contact.ContactDtoHelper; import de.symeda.sormas.app.backend.customizableenum.CustomizableEnumValueDtoHelper; import de.symeda.sormas.app.backend.disease.DiseaseConfigurationDtoHelper; +import de.symeda.sormas.app.backend.event.Event; import de.symeda.sormas.app.backend.event.EventDtoHelper; import de.symeda.sormas.app.backend.event.EventParticipantDtoHelper; import de.symeda.sormas.app.backend.facility.FacilityDtoHelper; import de.symeda.sormas.app.backend.feature.FeatureConfigurationDtoHelper; +import de.symeda.sormas.app.backend.immunization.Immunization; import de.symeda.sormas.app.backend.immunization.ImmunizationDtoHelper; import de.symeda.sormas.app.backend.infrastructure.InfrastructureHelper; import de.symeda.sormas.app.backend.infrastructure.PointOfEntryDtoHelper; @@ -92,6 +96,7 @@ import de.symeda.sormas.app.backend.sample.AdditionalTestDtoHelper; import de.symeda.sormas.app.backend.sample.PathogenTestDtoHelper; import de.symeda.sormas.app.backend.sample.SampleDtoHelper; +import de.symeda.sormas.app.backend.task.Task; import de.symeda.sormas.app.backend.task.TaskDtoHelper; import de.symeda.sormas.app.backend.therapy.PrescriptionDtoHelper; import de.symeda.sormas.app.backend.therapy.TreatmentDtoHelper; @@ -364,36 +369,30 @@ private void synchronizeChangedData() throws DaoException, NoConnectionException boolean treatmentsNeedPull = treatmentDtoHelper.pullAndPushEntities(context, syncCallbacks); boolean clinicalVisitsNeedPull = clinicalVisitDtoHelper.pullAndPushEntities(context, syncCallbacks); - boolean casesVisible = DtoUserRightsHelper.isViewAllowed(CaseDataDto.class) - && DtoFeatureConfigHelper.isFeatureConfigForCaseEnabled(); - boolean immunizationsVisible = DtoUserRightsHelper.isViewAllowed(ImmunizationDto.class) - && DtoFeatureConfigHelper.isFeatureConfigForImmunizationEnabled(); - boolean eventsVisible = DtoUserRightsHelper.isViewAllowed(EventDto.class) - && DtoFeatureConfigHelper.isFeatureConfigForEventsEnabled(); - boolean eventParticipantsVisible = DtoUserRightsHelper.isViewAllowed(EventParticipantDto.class) - && DtoFeatureConfigHelper.isFeatureConfigForEventParticipantsEnabled(); - boolean samplesVisible = DtoUserRightsHelper.isViewAllowed(SampleDto.class) - && DtoFeatureConfigHelper.isFeatureConfigForSampleEnabled(); - boolean sampleTestsVisible = DtoUserRightsHelper.isViewAllowed(PathogenTestDto.class) - && DtoFeatureConfigHelper.isFeatureConfigForSampleTestsEnabled(); - boolean additionalTestsVisible = DtoUserRightsHelper.isViewAllowed(AdditionalTestDto.class) - && DtoFeatureConfigHelper.isFeatureConfigForAdditionalTestsEnabled(); - boolean contactsVisible = DtoUserRightsHelper.isViewAllowed(ContactDto.class) - && DtoFeatureConfigHelper.isFeatureConfigForContactsEnabled(); - boolean visitsVisible = DtoUserRightsHelper.isViewAllowed(VisitDto.class) - && DtoFeatureConfigHelper.isFeatureConfigForVisitsEnabled(); - boolean tasksVisible = DtoUserRightsHelper.isViewAllowed(TaskDto.class) - && DtoFeatureConfigHelper.isFeatureConfigForTasksEnabled(); - boolean weeklyReportsVisible = DtoUserRightsHelper.isViewAllowed(WeeklyReportDto.class) - && DtoFeatureConfigHelper.isFeatureConfigForWeeklyReportsEnabled(); - boolean aggregateReportsVisible = DtoUserRightsHelper.isViewAllowed(AggregateReportDto.class) - && DtoFeatureConfigHelper.isFeatureConfigForAggregateReportsEnabled(); - boolean prescriptionsVisible = DtoUserRightsHelper.isViewAllowed(PrescriptionDto.class) - && DtoFeatureConfigHelper.isFeatureConfigForPrescriptionsEnabled(); - boolean treatmentsVisible = DtoUserRightsHelper.isViewAllowed(TreatmentDto.class) - && DtoFeatureConfigHelper.isFeatureConfigForTreatmentsEnabled(); - boolean clinicalVisitsVisible = DtoUserRightsHelper.isViewAllowed(ClinicalVisitDto.class) - && DtoFeatureConfigHelper.isFeatureConfigForClinicalVisitsEnabled(); + boolean casesVisible = DtoUserRightsHelper.isViewAllowed(CaseDataDto.class) && DtoFeatureConfigHelper.isFeatureConfigForCaseEnabled(); + boolean immunizationsVisible = + DtoUserRightsHelper.isViewAllowed(ImmunizationDto.class) && DtoFeatureConfigHelper.isFeatureConfigForImmunizationEnabled(); + boolean eventsVisible = DtoUserRightsHelper.isViewAllowed(EventDto.class) && DtoFeatureConfigHelper.isFeatureConfigForEventsEnabled(); + boolean eventParticipantsVisible = + DtoUserRightsHelper.isViewAllowed(EventParticipantDto.class) && DtoFeatureConfigHelper.isFeatureConfigForEventParticipantsEnabled(); + boolean samplesVisible = DtoUserRightsHelper.isViewAllowed(SampleDto.class) && DtoFeatureConfigHelper.isFeatureConfigForSampleEnabled(); + boolean sampleTestsVisible = + DtoUserRightsHelper.isViewAllowed(PathogenTestDto.class) && DtoFeatureConfigHelper.isFeatureConfigForSampleTestsEnabled(); + boolean additionalTestsVisible = + DtoUserRightsHelper.isViewAllowed(AdditionalTestDto.class) && DtoFeatureConfigHelper.isFeatureConfigForAdditionalTestsEnabled(); + boolean contactsVisible = DtoUserRightsHelper.isViewAllowed(ContactDto.class) && DtoFeatureConfigHelper.isFeatureConfigForContactsEnabled(); + boolean visitsVisible = DtoUserRightsHelper.isViewAllowed(VisitDto.class) && DtoFeatureConfigHelper.isFeatureConfigForVisitsEnabled(); + boolean tasksVisible = DtoUserRightsHelper.isViewAllowed(TaskDto.class) && DtoFeatureConfigHelper.isFeatureConfigForTasksEnabled(); + boolean weeklyReportsVisible = + DtoUserRightsHelper.isViewAllowed(WeeklyReportDto.class) && DtoFeatureConfigHelper.isFeatureConfigForWeeklyReportsEnabled(); + boolean aggregateReportsVisible = + DtoUserRightsHelper.isViewAllowed(AggregateReportDto.class) && DtoFeatureConfigHelper.isFeatureConfigForAggregateReportsEnabled(); + boolean prescriptionsVisible = + DtoUserRightsHelper.isViewAllowed(PrescriptionDto.class) && DtoFeatureConfigHelper.isFeatureConfigForPrescriptionsEnabled(); + boolean treatmentsVisible = + DtoUserRightsHelper.isViewAllowed(TreatmentDto.class) && DtoFeatureConfigHelper.isFeatureConfigForTreatmentsEnabled(); + boolean clinicalVisitsVisible = + DtoUserRightsHelper.isViewAllowed(ClinicalVisitDto.class) && DtoFeatureConfigHelper.isFeatureConfigForClinicalVisitsEnabled(); syncCallbacks.ifPresent(c -> c.getUpdateSynchronizationStepCallback().accept(SynchronizationDialog.SynchronizationStep.PULL_MODIFIED)); @@ -646,6 +645,11 @@ private void pullAndRemoveObsoleteUuidsSince(Date since) throws NoConnectionExce for (String caseUuid : caseUuids) { DatabaseHelper.getCaseDao().deleteCaseAndAllDependingEntities(caseUuid); } + // Remove obsolete cases based on change date + List obsoleteCases = DatabaseHelper.getCaseDao().queryForObsolete(); + for (Case obsoleteCase : obsoleteCases) { + DatabaseHelper.getCaseDao().deleteCaseAndAllDependingEntities(obsoleteCase.getUuid()); + } } syncCallbacks.ifPresent(c -> c.getLoadNextCallback().run()); @@ -656,6 +660,11 @@ private void pullAndRemoveObsoleteUuidsSince(Date since) throws NoConnectionExce for (String contactUuid : contactUuids) { DatabaseHelper.getContactDao().deleteContactAndAllDependingEntities(contactUuid); } + // Remove obsolete contacts based on change date + List obsoleteContacts = DatabaseHelper.getContactDao().queryForObsolete(); + for (Contact obsoleteContact : obsoleteContacts) { + DatabaseHelper.getContactDao().deleteContactAndAllDependingEntities(obsoleteContact.getUuid()); + } } syncCallbacks.ifPresent(c -> c.getLoadNextCallback().run()); @@ -665,6 +674,11 @@ private void pullAndRemoveObsoleteUuidsSince(Date since) throws NoConnectionExce for (String eventUuid : eventUuids) { DatabaseHelper.getEventDao().deleteEventAndAllDependingEntities(eventUuid); } + // Remove obsolete events based on change date + List obsoleteEvents = DatabaseHelper.getEventDao().queryForObsolete(); + for (Event obsoleteEvent : obsoleteEvents) { + DatabaseHelper.getEventDao().deleteEventAndAllDependingEntities(obsoleteEvent.getUuid()); + } } syncCallbacks.ifPresent(c -> c.getLoadNextCallback().run()); @@ -685,6 +699,11 @@ private void pullAndRemoveObsoleteUuidsSince(Date since) throws NoConnectionExce for (String immunizationUuid : immunizationUuids) { DatabaseHelper.getImmunizationDao().deleteImmunizationAndAllDependingEntities(immunizationUuid); } + // Remove obsolete immunizations based on change date + List obsoleteImmunizations = DatabaseHelper.getImmunizationDao().queryForObsolete(); + for (Immunization obsoleteImmunization : obsoleteImmunizations) { + DatabaseHelper.getImmunizationDao().deleteImmunizationAndAllDependingEntities(obsoleteImmunization.getUuid()); + } } syncCallbacks.ifPresent(c -> c.getLoadNextCallback().run()); @@ -704,6 +723,11 @@ private void pullAndRemoveObsoleteUuidsSince(Date since) throws NoConnectionExce for (String taskUuid : taskUuids) { DatabaseHelper.getTaskDao().deleteTaskAndAllDependingEntities(taskUuid); } + // Remove obsolete tasks based on change date + List obsoleteTasks = DatabaseHelper.getTaskDao().queryForObsolete(); + for (Task obsoleteTask : obsoleteTasks) { + DatabaseHelper.getTaskDao().deleteTaskAndAllDependingEntities(obsoleteTask.getUuid()); + } } syncCallbacks.ifPresent(c -> c.getLoadNextCallback().run()); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/action/ActionService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/action/ActionService.java index 5c884114f05..8fbd46d59e6 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/action/ActionService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/action/ActionService.java @@ -74,16 +74,6 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c return filter; } - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public List getAllActiveUuids() { CriteriaBuilder cb = em.getCriteriaBuilder(); @@ -126,15 +116,7 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return createUserFilter(new ActionQueryContext(cb, cq, from), true); - } - public Predicate createUserFilter(ActionQueryContext queryContext) { - return createUserFilter(queryContext, false); - } - public Predicate createUserFilter(ActionQueryContext queryContext, boolean obsolete) { CriteriaQuery cq = queryContext.getQuery(); CriteriaBuilder cb = queryContext.getCriteriaBuilder(); @@ -151,12 +133,7 @@ public Predicate createUserFilter(ActionQueryContext queryContext, boolean obsol } Predicate filter = cb.equal(joins.getCreator(), currentUser); - Predicate eventFilter; - if (obsolete) { - eventFilter = eventService.createUserFilterForObsoleteSync(new EventQueryContext(cb, cq, joins.getEventJoins())); - } else { - eventFilter = eventService.createUserFilter(new EventQueryContext(cb, cq, joins.getEventJoins())); - } + Predicate eventFilter = eventService.createUserFilter(new EventQueryContext(cb, cq, joins.getEventJoins())); if (eventFilter != null) { filter = cb.or(filter, eventFilter); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java index fc0e6641934..14b18aebdcf 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/CampaignService.java @@ -31,26 +31,11 @@ protected Predicate createUserFilterInternal(CriteriaBuilder cb, CriteriaQuery c return createUserFilter(new CampaignQueryContext(cb, cq, from)); } - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public Predicate createUserFilter(CampaignQueryContext queryContext) { // A user who has access to CampaignView can read all campaigns return null; } - @Override - public Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return null; - } - public Predicate buildCriteriaFilter(CampaignQueryContext queryContext, CampaignCriteria campaignCriteria) { CriteriaBuilder cb = queryContext.getCriteriaBuilder(); @@ -128,7 +113,7 @@ public Predicate createActiveCampaignsFilter(CriteriaBuilder cb, Root } @Override - public Predicate inJurisdictionOrOwned(CriteriaBuilder cb, CriteriaQuery query, From from) { + public Predicate inJurisdictionOrOwned(CriteriaBuilder cb, CriteriaQuery query, From from) { // Currently no jurisdiction checks for campaigns return cb.conjunction(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/data/CampaignFormDataService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/data/CampaignFormDataService.java index f2e2c2e69e4..cbd82be2871 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/data/CampaignFormDataService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/data/CampaignFormDataService.java @@ -130,21 +130,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return createUserFilter(cb, cq, from); - } - - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public List getAllActiveUuids() { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cq = cb.createQuery(String.class); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/diagram/CampaignDiagramDefinitionService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/diagram/CampaignDiagramDefinitionService.java index 1f82c63d1f6..a534247465c 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/diagram/CampaignDiagramDefinitionService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/diagram/CampaignDiagramDefinitionService.java @@ -26,21 +26,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public boolean diagramExists(@NotNull String diagramId) { return exists((cb, root, cq) -> cb.equal(root.get(CampaignDiagramDefinition.DIAGRAM_ID), diagramId)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/form/CampaignFormMetaService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/form/CampaignFormMetaService.java index 4bdecfc9d4b..143a4ec05f7 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/form/CampaignFormMetaService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/campaign/form/CampaignFormMetaService.java @@ -29,21 +29,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public List getCampaignFormMetasAsReferencesByCampaign(String uuid) { CriteriaBuilder cb = em.getCriteriaBuilder(); 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 b062bf3fb10..33144d8ad3b 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 @@ -118,6 +118,7 @@ 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.common.LimitedChangeDateFilterProvider; import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.contact.ContactJoins; import de.symeda.sormas.backend.contact.ContactQueryContext; @@ -180,7 +181,7 @@ @Stateless @LocalBean -public class CaseService extends AbstractCoreAdoService { +public class CaseService extends AbstractCoreAdoService implements LimitedChangeDateFilterProvider { private static final Double SECONDS_30_DAYS = Long.valueOf(TimeUnit.DAYS.toSeconds(30L)).doubleValue(); @@ -611,7 +612,7 @@ public Predicate createObsoleteLimitedSyncCasePredicate(CriteriaBuilder cb, From @Override protected Predicate getUserFilterForObsoleteUuids(CriteriaBuilder cb, CriteriaQuery cq, Root from) { - return createUserFilterForObsoleteSync(new CaseQueryContext(cb, cq, from), new CaseUserFilterCriteria().excludeLimitedSyncRestrictions(true)); + return createUserFilter(new CaseQueryContext(cb, cq, from), new CaseUserFilterCriteria().excludeLimitedSyncRestrictions(true)); } /** @@ -1305,29 +1306,12 @@ protected Predicate createUserFilterInternal(CriteriaBuilder cb, CriteriaQuery c return createUserFilter(new CaseQueryContext(cb, cq, from)); } - @Override - public Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return createUserFilterForObsoleteSync(new CaseQueryContext(cb, cq, from)); - } - public Predicate createUserFilter(CaseQueryContext caseQueryContext) { return createUserFilter(caseQueryContext, null); } - public Predicate createUserFilterForObsoleteSync(CaseQueryContext caseQueryContext) { - return createUserFilter(caseQueryContext, null, true); - } - - public Predicate createUserFilter(CaseQueryContext caseQueryContext, CaseUserFilterCriteria userFilterCriteria) { - return createUserFilter(caseQueryContext, userFilterCriteria, false); - } - - public Predicate createUserFilterForObsoleteSync(CaseQueryContext caseQueryContext, CaseUserFilterCriteria userFilterCriteria) { - return createUserFilter(caseQueryContext, userFilterCriteria, true); - } - @SuppressWarnings("rawtypes") - public Predicate createUserFilter(CaseQueryContext caseQueryContext, CaseUserFilterCriteria userFilterCriteria, boolean obsolete) { + public Predicate createUserFilter(CaseQueryContext caseQueryContext, CaseUserFilterCriteria userFilterCriteria) { User currentUser = getCurrentUser(); if (currentUser == null) { @@ -1442,31 +1426,22 @@ public Predicate createUserFilter(CaseQueryContext caseQueryContext, CaseUserFil filter = CriteriaBuilderHelper.or(cb, filter, filterResponsible); - if ((userFilterCriteria == null || !userFilterCriteria.isExcludeLimitedSyncRestrictions()) - && featureConfigurationFacade - .isPropertyValueTrue(FeatureType.LIMITED_SYNCHRONIZATION, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES) - && RequestContextHolder.isMobileSync()) { - final Predicate limitedCaseSyncPredicate = cb.not( - cb.and( - cb.equal(casePath.get(Case.CASE_CLASSIFICATION), CaseClassification.NO_CASE), - cb.or( - cb.notEqual(casePath.get(Case.REPORTING_USER), currentUser), - cb.and(cb.equal(casePath.get(Case.REPORTING_USER), currentUser), cb.isNull(casePath.get(Case.CREATION_VERSION)))))); - filter = CriteriaBuilderHelper.and(cb, filter, limitedCaseSyncPredicate); - } - if (RequestContextHolder.isMobileSync()) { - if (obsolete) { - Predicate limitedChangeDateForObsoletePredicate = - CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilterForObsoleteEntities(cb, casePath)); - if (limitedChangeDateForObsoletePredicate != null) { - filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDateForObsoletePredicate); - } - } else { - Predicate limitedChangeDatePredicate = CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilter(cb, casePath)); - if (limitedChangeDatePredicate != null) { - filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDatePredicate); - } + if ((userFilterCriteria == null || !userFilterCriteria.isExcludeLimitedSyncRestrictions()) + && featureConfigurationFacade + .isPropertyValueTrue(FeatureType.LIMITED_SYNCHRONIZATION, FeatureTypeProperty.EXCLUDE_NO_CASE_CLASSIFIED_CASES)) { + final Predicate limitedCaseSyncPredicate = cb.not( + cb.and( + cb.equal(casePath.get(Case.CASE_CLASSIFICATION), CaseClassification.NO_CASE), + cb.or( + cb.notEqual(casePath.get(Case.REPORTING_USER), currentUser), + cb.and(cb.equal(casePath.get(Case.REPORTING_USER), currentUser), cb.isNull(casePath.get(Case.CREATION_VERSION)))))); + filter = CriteriaBuilderHelper.and(cb, filter, limitedCaseSyncPredicate); + } + + Predicate limitedChangeDatePredicate = CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilter(cb, casePath)); + if (limitedChangeDatePredicate != null) { + filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDatePredicate); } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportService.java index 3ae08c54769..1921730d928 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportService.java @@ -83,21 +83,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - @Override public boolean inJurisdictionOrOwned(SurveillanceReport entity) { return fulfillsCondition(entity, this::inJurisdictionOrOwned); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java index 1efcd3cecda..fd86594163f 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitService.java @@ -15,7 +15,6 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; -import de.symeda.sormas.api.RequestContextHolder; import de.symeda.sormas.api.clinicalcourse.ClinicalVisitCriteria; import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.caze.CaseJoins; @@ -38,16 +37,6 @@ public ClinicalVisitService() { super(ClinicalVisit.class); } - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public List findBy(ClinicalVisitCriteria criteria) { CriteriaBuilder cb = em.getCriteriaBuilder(); @@ -100,13 +89,6 @@ public List getAllActiveUuids(User user) { filter = CriteriaBuilderHelper.and(cb, filter, userFilter); } - if (RequestContextHolder.isMobileSync()) { - Predicate predicate = createLimitedChangeDateFilter(cb, from); - if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, filter, predicate); - } - } - cq.where(filter); cq.select(from.get(ClinicalVisit.UUID)); @@ -147,13 +129,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - Join clinicalCourse = from.join(ClinicalVisit.CLINICAL_COURSE, JoinType.LEFT); - return caseService - .createUserFilterForObsoleteSync(new CaseQueryContext(cb, cq, new CaseJoins(clinicalCourse.join(ClinicalCourse.CASE, JoinType.LEFT)))); - } - @Override public boolean inJurisdictionOrOwned(ClinicalVisit entity) { return fulfillsCondition(entity, this::inJurisdictionOrOwned); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractInfrastructureAdoService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractInfrastructureAdoService.java index 061f5817802..a836116daf2 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractInfrastructureAdoService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractInfrastructureAdoService.java @@ -6,7 +6,6 @@ import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.From; import javax.persistence.criteria.Join; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; @@ -33,21 +32,6 @@ public Predicate createBasicFilter(CriteriaBuilder cb, Root root) { return cb.isFalse(root.get(InfrastructureAdo.ARCHIVED)); } - @Override - public Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public List getAllActive() { CriteriaBuilder cb = em.getCriteriaBuilder(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java index 0923b173490..47dc77d7818 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java @@ -1,6 +1,5 @@ package de.symeda.sormas.backend.common; -import java.sql.Timestamp; import java.util.Collections; import java.util.Date; import java.util.List; @@ -13,13 +12,12 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; +import org.apache.commons.lang3.StringUtils; + import de.symeda.sormas.api.RequestContextHolder; import de.symeda.sormas.api.feature.FeatureType; import de.symeda.sormas.api.feature.FeatureTypeProperty; -import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; -import org.apache.commons.lang3.StringUtils; - import de.symeda.sormas.backend.user.User; /** @@ -28,7 +26,8 @@ * @param * JPA entity managed by this Service. */ -public abstract class AdoServiceWithUserFilterAndJurisdiction extends BaseAdoService { +public abstract class AdoServiceWithUserFilterAndJurisdiction extends BaseAdoService + implements EmptyLimitedChangeDateFilterProvider { public static final int NR_OF_LAST_PHONE_DIGITS_TO_SEARCH = 6; @EJB @@ -44,30 +43,22 @@ protected AdoServiceWithUserFilterAndJurisdiction(Class elementClass) { @SuppressWarnings("rawtypes") public abstract Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from); - public abstract Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from); - + /** + * Returns a filter that limits the data retrieved by a query to data that has been changed in the last X days, + * where X is the max change date period specified by the limited synchronization feature type in the database. + */ protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_PERIOD, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Date maxChangeDate = DateHelper.subtractDays(new Date(), maxChangeDatePeriod); - Timestamp timestamp = Timestamp.from(DateHelper.getStartOfDay(maxChangeDate).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(ADO.CHANGE_DATE), timestamp)); - } - return null; - } - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - final Integer maxChangeDatePeriod = featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_PERIOD, Integer.class); - if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) - && maxChangeDatePeriod != null && maxChangeDatePeriod != -1) { - Date maxChangeDate = DateHelper.subtractDays(new Date(), maxChangeDatePeriod); - Timestamp timestamp = Timestamp.from(DateHelper.getStartOfDay(maxChangeDate).toInstant()); - return CriteriaBuilderHelper.or(cb, cb.lessThan(from.get(ADO.CHANGE_DATE), timestamp)); + if (hasLimitedChangeDateFilterImplementation()) { + return createLimitedChangeDateFilter( + cb, + from, + featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION), + featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_PERIOD, Integer.class)); + } else { + return createEmptyLimitedChangeDateFilter(); } - return null; } /** @@ -135,15 +126,6 @@ public List getAllIds(User user) { if (user != null) { Predicate filter = createUserFilter(cb, cq, from); - - if (RequestContextHolder.isMobileSync()) - { - Predicate predicate = createLimitedChangeDateFilter(cb, from); - if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, filter, predicate); - } - } - if (filter != null) { cq.where(filter); } @@ -180,13 +162,6 @@ public List getObsoleteUuidsSince(Date since) { filter = CriteriaBuilderHelper.and(cb, filter, contentFilter); - if (RequestContextHolder.isMobileSync()) { - Predicate predicate = createLimitedChangeDateFilterForObsoleteEntities(cb, from); - if (predicate != null) { - filter = CriteriaBuilderHelper.or(cb, filter, predicate); - } - } - cq.where(filter); cq.select(from.get(AbstractDomainObject.UUID)); @@ -194,11 +169,7 @@ public List getObsoleteUuidsSince(Date since) { } protected Predicate getUserFilterForObsoleteUuids(CriteriaBuilder cb, CriteriaQuery cq, Root from) { - if (RequestContextHolder.isMobileSync()) { - return createUserFilterForObsoleteSync(cb, cq, from); - } else { - return createUserFilter(cb, cq, from); - } + return createUserFilter(cb, cq, from); } protected List getAdditionalObsoleteUuidsPredicates(Date since, CriteriaBuilder cb, CriteriaQuery cq, Root from) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/EmptyLimitedChangeDateFilterProvider.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/EmptyLimitedChangeDateFilterProvider.java new file mode 100644 index 00000000000..c93e851e751 --- /dev/null +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/EmptyLimitedChangeDateFilterProvider.java @@ -0,0 +1,18 @@ +package de.symeda.sormas.backend.common; + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.From; +import javax.persistence.criteria.Predicate; + +public interface EmptyLimitedChangeDateFilterProvider extends LimitedChangeDateFilterProvider { + + @Override + default Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from, boolean featureEnabled, Integer maxChangeDatePeriod) { + return createEmptyLimitedChangeDateFilter(); + } + + @Override + default boolean hasLimitedChangeDateFilterImplementation() { + return false; + } +} diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/LimitedChangeDateFilterProvider.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/LimitedChangeDateFilterProvider.java new file mode 100644 index 00000000000..a74104d86c8 --- /dev/null +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/LimitedChangeDateFilterProvider.java @@ -0,0 +1,33 @@ +package de.symeda.sormas.backend.common; + +import java.sql.Timestamp; +import java.util.Date; + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.From; +import javax.persistence.criteria.Predicate; + +import de.symeda.sormas.api.utils.DateHelper; + +public interface LimitedChangeDateFilterProvider { + + default Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from, boolean featureEnabled, Integer maxChangeDatePeriod) { + + if (featureEnabled && maxChangeDatePeriod != null && maxChangeDatePeriod >= 0) { + Date maxChangeDate = DateHelper.subtractDays(new Date(), maxChangeDatePeriod); + Timestamp timestamp = Timestamp.from(DateHelper.getStartOfDay(maxChangeDate).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(ADO.CHANGE_DATE), timestamp)); + } + + return null; + } + + default Predicate createEmptyLimitedChangeDateFilter() { + return null; + } + + default boolean hasLimitedChangeDateFilterImplementation() { + return true; + } + +} diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java index d09fe52949f..59614e71f6d 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java @@ -97,6 +97,7 @@ import de.symeda.sormas.backend.common.CriteriaBuilderHelper; import de.symeda.sormas.backend.common.DeletableAdo; import de.symeda.sormas.backend.common.JurisdictionFlagsService; +import de.symeda.sormas.backend.common.LimitedChangeDateFilterProvider; import de.symeda.sormas.backend.contact.transformers.ContactListEntryDtoResultTransformer; import de.symeda.sormas.backend.disease.DiseaseConfigurationFacadeEjb.DiseaseConfigurationFacadeEjbLocal; import de.symeda.sormas.backend.document.DocumentService; @@ -138,7 +139,8 @@ @Stateless @LocalBean public class ContactService extends AbstractCoreAdoService - implements JurisdictionFlagsService { + implements JurisdictionFlagsService, + LimitedChangeDateFilterProvider { @EJB private CaseService caseService; @@ -505,7 +507,7 @@ protected List getAdditionalObsoleteUuidsPredicates(Date since, Crite @Override protected Predicate getUserFilterForObsoleteUuids(CriteriaBuilder cb, CriteriaQuery cq, Root from) { - return createUserFilterForObsoleteSync(new ContactQueryContext(cb, cq, from), new ContactCriteria().excludeLimitedSyncRestrictions(true)); + return createUserFilter(new ContactQueryContext(cb, cq, from), new ContactCriteria().excludeLimitedSyncRestrictions(true)); } public Long countContactsForMap(Region region, District district, Disease disease, Date from, Date to) { @@ -1004,49 +1006,24 @@ protected Predicate createUserFilterInternal(CriteriaBuilder cb, CriteriaQuery c return createUserFilter(new ContactQueryContext(cb, cq, from)); } - @Override - public Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return createUserFilterForObsoleteSync(new ContactQueryContext(cb, cq, from)); - } - public Predicate createUserFilter(ContactQueryContext queryContext) { return createUserFilter(queryContext, null); } - public Predicate createUserFilterForObsoleteSync(ContactQueryContext queryContext) { - return createUserFilter(queryContext, null, true); - } - public Predicate createUserFilter(ContactQueryContext contactQueryContext, ContactCriteria contactCriteria) { - return createUserFilter(contactQueryContext, contactCriteria, false); - } - - public Predicate createUserFilterForObsoleteSync(ContactQueryContext contactQueryContext, ContactCriteria contactCriteria) { - return createUserFilter(contactQueryContext, contactCriteria, true); - } - - public Predicate createUserFilter(ContactQueryContext contactQueryContext, ContactCriteria contactCriteria, boolean obsolete) { - Predicate userFilter = null; + Predicate userFilter; CriteriaQuery cq = contactQueryContext.getQuery(); CriteriaBuilder cb = contactQueryContext.getCriteriaBuilder(); CaseQueryContext caseQueryContext = new CaseQueryContext(cb, cq, contactQueryContext.getJoins().getCaseJoins()); if (contactCriteria == null || contactCriteria.getIncludeContactsFromOtherJurisdictions()) { - if (obsolete) { - userFilter = caseService.createUserFilterForObsoleteSync(caseQueryContext); - } else { - userFilter = caseService.createUserFilter(caseQueryContext); - } + userFilter = caseService.createUserFilter(caseQueryContext); } else { CaseUserFilterCriteria userFilterCriteria = new CaseUserFilterCriteria().excludeLimitedSyncRestrictions(contactCriteria.isExcludeLimitedSyncRestrictions()); - if (obsolete) { - userFilter = caseService.createUserFilterForObsoleteSync(caseQueryContext, userFilterCriteria); - } else { - userFilter = caseService.createUserFilter(caseQueryContext, userFilterCriteria); - } + userFilter = caseService.createUserFilter(caseQueryContext, userFilterCriteria); } Predicate filter; @@ -1057,19 +1034,12 @@ public Predicate createUserFilter(ContactQueryContext contactQueryContext, Conta } if (RequestContextHolder.isMobileSync()) { - if (obsolete) { - Predicate limitedChangeDateForObsoletePredicate = - CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilterForObsoleteEntities(cb, contactQueryContext.getRoot())); - if (limitedChangeDateForObsoletePredicate != null) { - filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDateForObsoletePredicate); - } - } else { - Predicate limitedChangeDatePredicate = CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilter(cb, contactQueryContext.getRoot())); - if (limitedChangeDatePredicate != null) { - filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDatePredicate); - } + Predicate limitedChangeDatePredicate = CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilter(cb, contactQueryContext.getRoot())); + if (limitedChangeDatePredicate != null) { + filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDatePredicate); } } + return filter; } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/customizableenum/CustomizableEnumValueService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/customizableenum/CustomizableEnumValueService.java index 1245f11ca4a..7348b3ce4eb 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/customizableenum/CustomizableEnumValueService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/customizableenum/CustomizableEnumValueService.java @@ -38,18 +38,4 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/disease/DiseaseConfigurationService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/disease/DiseaseConfigurationService.java index 229fc1565da..754624b8903 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/disease/DiseaseConfigurationService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/disease/DiseaseConfigurationService.java @@ -57,18 +57,4 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/document/DocumentService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/document/DocumentService.java index efe439b202d..70132b8b992 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/document/DocumentService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/document/DocumentService.java @@ -47,21 +47,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public void markAsDeleted(Document deleteme) { deleteme.setDeleted(true); em.persist(deleteme); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventGroupService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventGroupService.java index 5d9c62cfe29..3fafadb7bbe 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventGroupService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventGroupService.java @@ -66,21 +66,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return createUserFilter(cb, cq, from); - } - - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - @SuppressWarnings("rawtypes") public Predicate createUserFilter( CriteriaBuilder cb, diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java index df03e882461..7a084f8623e 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantService.java @@ -40,7 +40,6 @@ import de.symeda.sormas.api.Disease; import de.symeda.sormas.api.EditPermissionType; import de.symeda.sormas.api.EntityRelevanceStatus; -import de.symeda.sormas.api.RequestContextHolder; import de.symeda.sormas.api.caze.VaccinationStatus; import de.symeda.sormas.api.common.DeletionDetails; import de.symeda.sormas.api.event.EventParticipantCriteria; @@ -106,16 +105,6 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c return filter; } - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public List getAllActiveUuids(User user) { CriteriaBuilder cb = em.getCriteriaBuilder(); @@ -134,13 +123,6 @@ public List getAllActiveUuids(User user) { filter = CriteriaBuilderHelper.and(cb, filter, userFilter); } - if (RequestContextHolder.isMobileSync()) { - Predicate predicate = createLimitedChangeDateFilter(cb, from); - if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, filter, predicate); - } - } - cq.where(filter); cq.select(from.get(EventParticipant.UUID)); @@ -291,42 +273,21 @@ protected Predicate createUserFilterInternal(CriteriaBuilder cb, CriteriaQuery c return createUserFilter(new EventParticipantQueryContext(cb, cq, from)); } - @Override - public Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return createUserFilterForObsoleteSync(new EventParticipantQueryContext(cb, cq, from)); - } - public Predicate createUserFilter(EventParticipantQueryContext eventParticipantQueryContext) { final EventUserFilterCriteria eventUserFilterCriteria = new EventUserFilterCriteria(); eventUserFilterCriteria.includeUserCaseAndEventParticipantFilter(true); eventUserFilterCriteria.forceRegionJurisdiction(true); - return createUserFilter(eventParticipantQueryContext, eventUserFilterCriteria, false); - } - - public Predicate createUserFilterForObsoleteSync(EventParticipantQueryContext eventParticipantQueryContext) { - final EventUserFilterCriteria eventUserFilterCriteria = new EventUserFilterCriteria(); - eventUserFilterCriteria.includeUserCaseAndEventParticipantFilter(true); - eventUserFilterCriteria.forceRegionJurisdiction(true); - - return createUserFilter(eventParticipantQueryContext, eventUserFilterCriteria, true); + return createUserFilter(eventParticipantQueryContext, eventUserFilterCriteria); } public Predicate createUserFilter(EventParticipantQueryContext epqc, EventUserFilterCriteria eventUserFilterCriteria) { - return createUserFilter(epqc, eventUserFilterCriteria, false); - } - - public Predicate createUserFilter(EventParticipantQueryContext epqc, EventUserFilterCriteria eventUserFilterCriteria, boolean obsolete) { final CriteriaBuilder cb = epqc.getCriteriaBuilder(); final CriteriaQuery cq = epqc.getQuery(); final EventParticipantJoins joins = epqc.getJoins(); - if (obsolete) { - return eventService.createUserFilterForObsoleteSync(new EventQueryContext(cb, cq, joins.getEventJoins()), eventUserFilterCriteria); - } else { - return eventService.createUserFilter(new EventQueryContext(cb, cq, joins.getEventJoins()), eventUserFilterCriteria); - } + return eventService.createUserFilter(new EventQueryContext(cb, cq, joins.getEventJoins()), eventUserFilterCriteria); } public EventParticipant getByEventAndPerson(String eventUuid, String personUuid) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java index d6d643b3f41..62a54aae91b 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java @@ -40,13 +40,13 @@ import javax.persistence.criteria.Subquery; import javax.transaction.Transactional; -import de.symeda.sormas.api.RequestContextHolder; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import de.symeda.sormas.api.Disease; import de.symeda.sormas.api.EditPermissionType; import de.symeda.sormas.api.EntityRelevanceStatus; +import de.symeda.sormas.api.RequestContextHolder; import de.symeda.sormas.api.common.DeletionDetails; import de.symeda.sormas.api.document.DocumentRelatedEntityType; import de.symeda.sormas.api.event.EventCriteria; @@ -74,6 +74,7 @@ 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.common.LimitedChangeDateFilterProvider; import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.document.DocumentService; import de.symeda.sormas.backend.externalsurveillancetool.ExternalSurveillanceToolGatewayFacadeEjb; @@ -106,7 +107,7 @@ @Stateless @LocalBean -public class EventService extends AbstractCoreAdoService { +public class EventService extends AbstractCoreAdoService implements LimitedChangeDateFilterProvider { @EJB private EventParticipantService eventParticipantService; @@ -401,28 +402,11 @@ protected Predicate createUserFilterInternal(CriteriaBuilder cb, CriteriaQuery c return createUserFilter(new EventQueryContext(cb, cq, from)); } - @Override - public Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return createUserFilterForObsoleteSync(new EventQueryContext(cb, cq, from)); - } - public Predicate createUserFilter(EventQueryContext queryContext) { - return createUserFilter(queryContext, null, false); - } - - public Predicate createUserFilterForObsoleteSync(EventQueryContext queryContext) { - return createUserFilter(queryContext, null, true); + return createUserFilter(queryContext, null); } - public Predicate createUserFilter(EventQueryContext queryContext, EventUserFilterCriteria eventUserFilterCriteria) { - return createUserFilter(queryContext, eventUserFilterCriteria, false); - } - - public Predicate createUserFilterForObsoleteSync(EventQueryContext queryContext, EventUserFilterCriteria eventUserFilterCriteria) { - return createUserFilter(queryContext, eventUserFilterCriteria, true); - } - - public Predicate createUserFilter(final EventQueryContext queryContext, final EventUserFilterCriteria eventUserFilterCriteria, final boolean obsolete) { + public Predicate createUserFilter(final EventQueryContext queryContext, final EventUserFilterCriteria eventUserFilterCriteria) { User currentUser = getCurrentUser(); if (currentUser == null) { @@ -504,17 +488,9 @@ public Predicate createUserFilter(final EventQueryContext queryContext, final Ev } if (RequestContextHolder.isMobileSync()) { - if (obsolete) { - Predicate limitedChangeDateForObsoletePredicate = - CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilterForObsoleteEntities(cb, eventJoin)); - if (limitedChangeDateForObsoletePredicate != null) { - filter = CriteriaBuilderHelper.or(cb, filter, limitedChangeDateForObsoletePredicate); - } - } else { - Predicate limitedChangeDatePredicate = CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilter(cb, eventJoin)); - if (limitedChangeDatePredicate != null) { - filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDatePredicate); - } + Predicate limitedChangeDatePredicate = CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilter(cb, eventJoin)); + if (limitedChangeDatePredicate != null) { + filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDatePredicate); } } @@ -1068,7 +1044,7 @@ public Predicate inJurisdiction(EventQueryContext qc, User user) { } @Override - public Predicate inJurisdictionOrOwned(CriteriaBuilder cb, CriteriaQuery cq, From from) { + public Predicate inJurisdictionOrOwned(CriteriaBuilder cb, CriteriaQuery cq, From from) { return inJurisdictionOrOwned(new EventQueryContext(cb, cq, from)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageService.java index 69997e41c1a..5d45d872511 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageService.java @@ -76,21 +76,6 @@ public Predicate createDefaultFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public Predicate buildCriteriaFilter(CriteriaBuilder cb, Root labMessage, ExternalMessageCriteria criteria) { Predicate filter = null; if (criteria.getUuid() != null) { 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 0d9401774f2..a3bb93790f6 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 @@ -123,21 +123,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return createUserFilter(cb, cq, from); - } - - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public void createMissingFeatureConfigurations() { Map configs = getServerFeatureConfigurations(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/DirectoryImmunizationService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/DirectoryImmunizationService.java index e478e321945..178a39dedce 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/DirectoryImmunizationService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/DirectoryImmunizationService.java @@ -72,21 +72,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return createUserFilter(cb, cq, from); - } - - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public List getIndexList(ImmunizationCriteria criteria, Integer first, Integer max, List sortProperties) { final CriteriaBuilder cb = em.getCriteriaBuilder(); final CriteriaQuery cq = cb.createQuery(Object[].class); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java index 9fd743474ad..d9bd48d0bb2 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java @@ -48,15 +48,14 @@ import de.symeda.sormas.api.immunization.MeansOfImmunization; import de.symeda.sormas.api.sormastosormas.share.incoming.ShareRequestStatus; import de.symeda.sormas.api.user.UserRight; -import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.common.AbstractCoreAdoService; import de.symeda.sormas.backend.common.AbstractDomainObject; import de.symeda.sormas.backend.common.ChangeDateBuilder; import de.symeda.sormas.backend.common.ChangeDateFilterBuilder; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; +import de.symeda.sormas.backend.common.LimitedChangeDateFilterProvider; import de.symeda.sormas.backend.contact.Contact; -import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import de.symeda.sormas.backend.immunization.entity.DirectoryImmunization; import de.symeda.sormas.backend.immunization.entity.Immunization; import de.symeda.sormas.backend.immunization.transformers.ImmunizationListEntryDtoResultTransformer; @@ -80,7 +79,7 @@ @Stateless @LocalBean -public class ImmunizationService extends AbstractCoreAdoService { +public class ImmunizationService extends AbstractCoreAdoService implements LimitedChangeDateFilterProvider { @EJB private PersonService personService; @@ -90,8 +89,6 @@ public class ImmunizationService extends AbstractCoreAdoService { private SormasToSormasShareInfoFacadeEjbLocal sormasToSormasShareInfoFacade; @EJB private SormasToSormasShareInfoService sormasToSormasShareInfoService; - @EJB - protected FeatureConfigurationFacadeEjb.FeatureConfigurationFacadeEjbLocal featureConfigurationFacade; public ImmunizationService() { super(Immunization.class); @@ -501,11 +498,6 @@ protected Predicate createUserFilterInternal(CriteriaBuilder cb, CriteriaQuery c return createUserFilter(new ImmunizationQueryContext(cb, cq, from)); } - @Override - public Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return createUserFilter(new ImmunizationQueryContext(cb, cq, from)); - } - public Predicate createUserFilter(ImmunizationQueryContext qc) { User currentUser = getCurrentUser(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/PopulationDataService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/PopulationDataService.java index 84a39f91164..977c717099e 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/PopulationDataService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/infrastructure/PopulationDataService.java @@ -26,19 +26,20 @@ public PopulationDataService() { public Predicate buildCriteriaFilter(PopulationDataCriteria criteria, CriteriaBuilder cb, From from) { Predicate filter = null; if (criteria.getRegion() != null) { - filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.join(PopulationData.REGION, JoinType.LEFT).get(Region.UUID), criteria.getRegion().getUuid())); + filter = CriteriaBuilderHelper + .and(cb, filter, cb.equal(from.join(PopulationData.REGION, JoinType.LEFT).get(Region.UUID), criteria.getRegion().getUuid())); } if (criteria.isDistrictIsNull()) { filter = CriteriaBuilderHelper.and(cb, filter, cb.isNull(from.get(PopulationData.DISTRICT))); } else if (criteria.getDistrict() != null) { - filter = - CriteriaBuilderHelper.and(cb, filter, cb.equal(from.join(PopulationData.DISTRICT, JoinType.LEFT).get(District.UUID), criteria.getDistrict().getUuid())); + filter = CriteriaBuilderHelper + .and(cb, filter, cb.equal(from.join(PopulationData.DISTRICT, JoinType.LEFT).get(District.UUID), criteria.getDistrict().getUuid())); } if (criteria.isCommunityIsNull()) { filter = CriteriaBuilderHelper.and(cb, filter, cb.isNull(from.get(PopulationData.COMMUNITY))); } else if (criteria.getCommunity() != null) { - filter = - CriteriaBuilderHelper.and(cb, filter, cb.equal(from.join(PopulationData.COMMUNITY, JoinType.LEFT).get(Community.UUID), criteria.getCommunity().getUuid())); + filter = CriteriaBuilderHelper + .and(cb, filter, cb.equal(from.join(PopulationData.COMMUNITY, JoinType.LEFT).get(Community.UUID), criteria.getCommunity().getUuid())); } if (criteria.isAgeGroupIsNull()) { filter = CriteriaBuilderHelper.and(cb, filter, cb.isNull(from.get(PopulationData.AGE_GROUP))); @@ -59,19 +60,4 @@ public Predicate buildCriteriaFilter(PopulationDataCriteria criteria, CriteriaBu public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { return null; } - - @Override - public Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/outbreak/OutbreakService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/outbreak/OutbreakService.java index 2443c68da54..54ccf0cb78d 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/outbreak/OutbreakService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/outbreak/OutbreakService.java @@ -57,16 +57,6 @@ public OutbreakService() { super(Outbreak.class); } - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public List queryByCriteria(OutbreakCriteria criteria, User user, String orderProperty, boolean asc) { CriteriaBuilder cb = em.getCriteriaBuilder(); @@ -170,11 +160,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return null; - } - public Predicate buildCriteriaFilter(OutbreakCriteria criteria, CriteriaBuilder cb, Root from) { Predicate filter = null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java index c575f7e3c48..162a8f448ff 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonService.java @@ -272,11 +272,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From obsolete!"); } - @Override - public Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return createUserFilter(cb, cq, from); - } - public Predicate createUserFilter(PersonQueryContext queryContext, PersonCriteria personCriteria) { /* @@ -315,16 +310,6 @@ public Predicate createUserFilter(PersonQueryContext queryContext, PersonCriteri return userFilter; } - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - /** * @return {@code null}, if the association is not permitted to query, * otherwise an appropriate {@link Predicate} for the given {@link PersonAssociation}. @@ -584,12 +569,6 @@ private List getAllAfter( filter = and(cb, filter, dateFilter); } - if (RequestContextHolder.isMobileSync()) { - Predicate predicate = createLimitedChangeDateFilter(cb, personJoin); - if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, filter, predicate); - } - } if (filter != null) { cq.where(filter); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java index 7040fac784d..3c0e47b6560 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/AggregateReportService.java @@ -36,16 +36,6 @@ public AggregateReportService() { super(AggregateReport.class); } - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public Predicate createCriteriaFilter( AggregateReportCriteria criteria, CriteriaBuilder cb, @@ -119,11 +109,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return createUserFilter(cb, cq, from); - } - @SuppressWarnings("rawtypes") public Predicate createUserFilter(AggregateReportQueryContext queryContext) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportEntryService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportEntryService.java index 2a88575099b..723cf3b2f16 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportEntryService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportEntryService.java @@ -60,19 +60,4 @@ public long getNumberOfNonZeroEntries(WeeklyReport report) { public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { return weeklyReportService.createUserFilter(cb, cq, from.join(WeeklyReportEntry.WEEKLY_REPORT, JoinType.LEFT)); } - - @Override - public Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return createUserFilter(cb, cq, from); - } - - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java index 30b458a5769..a39107b885f 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/report/WeeklyReportService.java @@ -62,16 +62,6 @@ public WeeklyReportService() { super(WeeklyReport.class); } - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public long getNumberOfWeeklyReportsByFacility(Facility facility, EpiWeek epiWeek) { CriteriaBuilder cb = em.getCriteriaBuilder(); @@ -154,11 +144,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return createUserFilter(cb, cq, from); - } - /** * Filters users analogous to reportingUsers in ::createUserFilter * diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java index a05f4121968..d97f828f8d8 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestService.java @@ -19,7 +19,6 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; -import de.symeda.sormas.api.RequestContextHolder; import de.symeda.sormas.api.sample.AdditionalTestCriteria; import de.symeda.sormas.api.utils.SortProperty; import de.symeda.sormas.backend.caze.Case; @@ -55,16 +54,6 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c return filter; } - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public Predicate buildCriteriaFilter(AdditionalTestCriteria additionalTestCriteria, CriteriaBuilder cb, Root from) { Predicate filter = createActiveSamplesFilter(cb, from); @@ -151,13 +140,6 @@ public List getAllActiveUuids(User user) { filter = CriteriaBuilderHelper.and(cb, filter, userFilter); } - if (RequestContextHolder.isMobileSync()) { - Predicate predicate = createLimitedChangeDateFilter(cb, from); - if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, filter, predicate); - } - } - cq.where(filter); cq.select(from.get(AdditionalTest.UUID)); @@ -184,7 +166,7 @@ public List getAllBySample(Sample sample) { * cases that are {@link Case#archived}, contacts that are {@link Contact#deleted}. or event participants that are * {@link EventParticipant#deleted} */ - private Predicate createActiveSamplesFilter(CriteriaBuilder cb, From root) { + private Predicate createActiveSamplesFilter(CriteriaBuilder cb, From root) { Join sample = root.join(AdditionalTest.SAMPLE, JoinType.LEFT); Join caze = sample.join(Sample.ASSOCIATED_CASE, JoinType.LEFT); @@ -209,11 +191,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return createUserFilter(cb, cq, from); - } - /** * @param additionalTestUuids * {@link AdditionalTest}s identified by {@code uuid} to be deleted. diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java index dfb567bceaa..5239f8cc384 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestService.java @@ -40,7 +40,6 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; -import de.symeda.sormas.api.RequestContextHolder; import de.symeda.sormas.api.common.DeletionDetails; import de.symeda.sormas.api.sample.PathogenTestCriteria; import de.symeda.sormas.api.sample.PathogenTestResultType; @@ -79,16 +78,6 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c return filter; } - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public List getAllActiveUuids(User user) { CriteriaBuilder cb = em.getCriteriaBuilder(); @@ -102,13 +91,6 @@ public List getAllActiveUuids(User user) { filter = CriteriaBuilderHelper.and(cb, filter, userFilter); } - if (RequestContextHolder.isMobileSync()) { - Predicate predicate = createLimitedChangeDateFilter(cb, from); - if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, filter, predicate); - } - } - cq.where(filter); cq.select(from.get(PathogenTest.UUID)); @@ -327,11 +309,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return createUserFilter(cb, cq, from); - } - @Override public void delete(PathogenTest pathogenTest, DeletionDetails deletionDetails) { super.delete(pathogenTest, deletionDetails); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java index 8220d4cb055..194b4886597 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java @@ -476,13 +476,6 @@ public List getAllActiveUuids(User user) { filter = CriteriaBuilderHelper.and(cb, filter, userFilter); } - if (RequestContextHolder.isMobileSync()) { - Predicate predicate = createLimitedChangeDateFilter(cb, from); - if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, filter, predicate); - } - } - cq.where(filter); cq.select(from.get(Sample.UUID)); @@ -583,17 +576,8 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return createUserFilter(new SampleQueryContext(cb, cq, from), null, true); - } - - public Predicate createUserFilter(SampleQueryContext sampleQueryContext, SampleCriteria criteria) { - return createUserFilter(sampleQueryContext, criteria, false); - } - @SuppressWarnings("rawtypes") - public Predicate createUserFilter(SampleQueryContext sampleQueryContext, SampleCriteria criteria, boolean obsolete) { + public Predicate createUserFilter(SampleQueryContext sampleQueryContext, SampleCriteria criteria) { final CriteriaQuery cq = sampleQueryContext.getQuery(); final CriteriaBuilder cb = sampleQueryContext.getCriteriaBuilder(); @@ -614,11 +598,7 @@ public Predicate createUserFilter(SampleQueryContext sampleQueryContext, SampleC if (criteria != null && criteria.getSampleAssociationType() != null && criteria.getSampleAssociationType() != SampleAssociationType.ALL) { final SampleAssociationType sampleAssociationType = criteria.getSampleAssociationType(); if (sampleAssociationType == SampleAssociationType.CASE) { - if (obsolete) { - filter = CriteriaBuilderHelper.or(cb, filter, caseService.createUserFilterForObsoleteSync(new CaseQueryContext(cb, cq, joins.getCaseJoins()), null)); - } else { - filter = CriteriaBuilderHelper.or(cb, filter, caseService.createUserFilter(new CaseQueryContext(cb, cq, joins.getCaseJoins()), null)); - } + filter = CriteriaBuilderHelper.or(cb, filter, caseService.createUserFilter(new CaseQueryContext(cb, cq, joins.getCaseJoins()), null)); } else if (sampleAssociationType == SampleAssociationType.CONTACT && !RequestContextHolder.isMobileSync()) { filter = CriteriaBuilderHelper .or(cb, filter, contactService.createUserFilter(new ContactQueryContext(cb, cq, joins.getContactJoins()), null)); @@ -628,53 +608,30 @@ public Predicate createUserFilter(SampleQueryContext sampleQueryContext, SampleC filter, eventParticipantService.createUserFilter(new EventParticipantQueryContext(cb, cq, joins.getEventParticipantJoins()))); } - } else { - Predicate caseUserFilter; - if (obsolete) { - caseUserFilter = caseService.createUserFilterForObsoleteSync(new CaseQueryContext(cb, cq, joins.getCaseJoins()), null); - } else { - caseUserFilter = caseService.createUserFilter(new CaseQueryContext(cb, cq, joins.getCaseJoins()), null); - } - if (currentUser.getLimitedDisease() != null) { - filter = CriteriaBuilderHelper.and( - cb, - filter, - CriteriaBuilderHelper.or( - cb, - caseUserFilter, - RequestContextHolder.isMobileSync() - ? null - : contactService.createUserFilter(new ContactQueryContext(cb, cq, joins.getContactJoins()), null), - RequestContextHolder.isMobileSync() - ? null - : eventParticipantService.createUserFilter(new EventParticipantQueryContext(cb, cq, joins.getEventParticipantJoins())))); - } else { - filter = CriteriaBuilderHelper.or( + } else if (currentUser.getLimitedDisease() != null) { + filter = CriteriaBuilderHelper.and( + cb, + filter, + CriteriaBuilderHelper.or( cb, - filter, - caseUserFilter, + caseService.createUserFilter(new CaseQueryContext(cb, cq, joins.getCaseJoins()), null), RequestContextHolder.isMobileSync() ? null : contactService.createUserFilter(new ContactQueryContext(cb, cq, joins.getContactJoins()), null), RequestContextHolder.isMobileSync() ? null - : eventParticipantService.createUserFilter(new EventParticipantQueryContext(cb, cq, joins.getEventParticipantJoins()))); - } - } - - if (RequestContextHolder.isMobileSync()) { - if (obsolete) { - Predicate limitedChangeDateForObsoletePredicate = - CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilterForObsoleteEntities(cb, sampleQueryContext.getRoot())); - if (limitedChangeDateForObsoletePredicate != null) { - filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDateForObsoletePredicate); - } - } else { - Predicate limitedChangeDatePredicate = CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilter(cb, sampleQueryContext.getRoot())); - if (limitedChangeDatePredicate != null) { - filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDatePredicate); - } - } + : eventParticipantService.createUserFilter(new EventParticipantQueryContext(cb, cq, joins.getEventParticipantJoins())))); + } else { + filter = CriteriaBuilderHelper.or( + cb, + filter, + caseService.createUserFilter(new CaseQueryContext(cb, cq, joins.getCaseJoins()), null), + RequestContextHolder.isMobileSync() + ? null + : contactService.createUserFilter(new ContactQueryContext(cb, cq, joins.getContactJoins()), null), + RequestContextHolder.isMobileSync() + ? null + : eventParticipantService.createUserFilter(new EventParticipantQueryContext(cb, cq, joins.getEventParticipantJoins()))); } return filter; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/share/ExternalShareInfoService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/share/ExternalShareInfoService.java index 83c4a17b203..51e2149b1aa 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/share/ExternalShareInfoService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/share/ExternalShareInfoService.java @@ -66,21 +66,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public Predicate buildCriteriaFilter(ExternalShareInfoCriteria criteria, CriteriaBuilder cb, Root shareInfo) { Predicate filter = null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/origin/SormasToSormasOriginInfoService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/origin/SormasToSormasOriginInfoService.java index 7d06b18880d..fa83128d65c 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/origin/SormasToSormasOriginInfoService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/origin/SormasToSormasOriginInfoService.java @@ -45,21 +45,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public SormasToSormasOriginInfo getByPerson(String personUuid) { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cq = cb.createQuery(SormasToSormasOriginInfo.class); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/incoming/SormasToSormasShareRequestService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/incoming/SormasToSormasShareRequestService.java index e057277721a..ebc7c052d48 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/incoming/SormasToSormasShareRequestService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/incoming/SormasToSormasShareRequestService.java @@ -58,21 +58,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public Predicate buildCriteriaFilter(ShareRequestCriteria criteria, CriteriaBuilder cb, Root root) { Predicate filter = null; if (criteria.getStatus() != null) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/ShareRequestInfoService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/ShareRequestInfoService.java index 252555a2a82..c6830491fcc 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/ShareRequestInfoService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/ShareRequestInfoService.java @@ -47,21 +47,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public Predicate buildCriteriaFilter(ShareRequestCriteria criteria, CriteriaBuilder cb, Root root) { Predicate filter = null; if (criteria.getStatus() != null) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfoService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfoService.java index 8ea02a6ab05..9a53ed3812a 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfoService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfoService.java @@ -71,22 +71,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - // no filter by user needed - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public Predicate buildCriteriaFilter(SormasToSormasShareInfoCriteria criteria, CriteriaBuilder cb, Root from) { Predicate filter = null; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java index 855457ef945..8f1efa60a6c 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java @@ -67,6 +67,7 @@ import de.symeda.sormas.backend.common.AdoServiceWithUserFilterAndJurisdiction; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; import de.symeda.sormas.backend.common.JurisdictionFlagsService; +import de.symeda.sormas.backend.common.LimitedChangeDateFilterProvider; import de.symeda.sormas.backend.common.TaskCreationException; import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.contact.ContactQueryContext; @@ -89,7 +90,7 @@ @Stateless @LocalBean public class TaskService extends AdoServiceWithUserFilterAndJurisdiction - implements JurisdictionFlagsService { + implements JurisdictionFlagsService, LimitedChangeDateFilterProvider { @EJB private CaseService caseService; @@ -158,11 +159,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return createUserFilter(new TaskQueryContext(cb, cq, from), null, true); - } - public Predicate createUserFilter(TaskQueryContext taskQueryContext) { return createUserFilter(taskQueryContext, null); } @@ -194,14 +190,6 @@ private boolean hasContextOrNoContext(TaskCriteria taskCriteria, TaskContext tas } public Predicate createUserFilter(TaskQueryContext taskQueryContext, TaskCriteria taskCriteria) { - return createUserFilter(taskQueryContext, taskCriteria, false); - } - - public Predicate createUserFilterForObsolete(TaskQueryContext taskQueryContext, TaskCriteria taskCriteria) { - return createUserFilter(taskQueryContext, taskCriteria, true); - } - - public Predicate createUserFilter(TaskQueryContext taskQueryContext, TaskCriteria taskCriteria, boolean obsolete) { User currentUser = getCurrentUser(); if (currentUser == null) { @@ -231,69 +219,34 @@ public Predicate createUserFilter(TaskQueryContext taskQueryContext, TaskCriteri Predicate filter = cb.equal(taskPath.get(Task.CREATOR_USER), currentUser); filter = cb.or(filter, cb.equal(taskPath.get(Task.ASSIGNEE_USER), currentUser)); - if (obsolete) - { - Predicate caseFilter = hasContextOrNoContext(taskCriteria, TaskContext.CASE) - ? caseService.createUserFilterForObsoleteSync( - new CaseQueryContext(cb, cq, joins.getCaseJoins()), - taskCriteria != null - ? new CaseUserFilterCriteria().excludeLimitedSyncRestrictions(taskCriteria.isExcludeLimitedSyncRestrictions()) - : null) - : null; - if (caseFilter != null) { - filter = cb.or(filter, caseFilter); - } - Predicate contactFilter = hasContextOrNoContext(taskCriteria, TaskContext.CONTACT) - ? contactService.createUserFilterForObsoleteSync(new ContactQueryContext(cb, cq, joins.getContactJoins())) - : null; - if (contactFilter != null) { - filter = cb.or( - filter, - CriteriaBuilderHelper - .or(cb, contactFilter, createAssigneeOrObserverFilter(cb, joins.getAssignee(), joins.getTaskObservers(), currentUser))); - } - Predicate eventFilter = hasContextOrNoContext(taskCriteria, TaskContext.EVENT) - ? eventService.createUserFilterForObsoleteSync(new EventQueryContext(cb, cq, joins.getEventJoins())) - : null; - if (eventFilter != null) { - filter = cb.or(filter, eventFilter); - } - } else { - Predicate caseFilter = hasContextOrNoContext(taskCriteria, TaskContext.CASE) - ? caseService.createUserFilter( - new CaseQueryContext(cb, cq, joins.getCaseJoins()), - taskCriteria != null - ? new CaseUserFilterCriteria().excludeLimitedSyncRestrictions(taskCriteria.isExcludeLimitedSyncRestrictions()) - : null) - : null; - if (caseFilter != null) { - filter = cb.or(filter, caseFilter); - } - Predicate contactFilter = hasContextOrNoContext(taskCriteria, TaskContext.CONTACT) - ? contactService.createUserFilter(new ContactQueryContext(cb, cq, joins.getContactJoins())) - : null; - if (contactFilter != null) { - filter = cb.or( - filter, - CriteriaBuilderHelper - .or(cb, contactFilter, createAssigneeOrObserverFilter(cb, joins.getAssignee(), joins.getTaskObservers(), currentUser))); - } - Predicate eventFilter = hasContextOrNoContext(taskCriteria, TaskContext.EVENT) - ? eventService.createUserFilter(new EventQueryContext(cb, cq, joins.getEventJoins())) - : null; - if (eventFilter != null) { - filter = cb.or(filter, eventFilter); - } - Predicate travelEntryFilter = hasContextOrNoContext(taskCriteria, TaskContext.TRAVEL_ENTRY) - ? travelEntryService.createUserFilter(new TravelEntryQueryContext(cb, cq, joins.getTravelEntryJoins())) - : null; - if (travelEntryFilter != null) { - filter = cb.or(filter, travelEntryFilter); - } + Predicate caseFilter = hasContextOrNoContext(taskCriteria, TaskContext.CASE) + ? caseService.createUserFilter( + new CaseQueryContext(cb, cq, joins.getCaseJoins()), + taskCriteria != null + ? new CaseUserFilterCriteria().excludeLimitedSyncRestrictions(taskCriteria.isExcludeLimitedSyncRestrictions()) + : null) + : null; + if (caseFilter != null) { + filter = cb.or(filter, caseFilter); + } + Predicate contactFilter = hasContextOrNoContext(taskCriteria, TaskContext.CONTACT) + ? contactService.createUserFilter(new ContactQueryContext(cb, cq, joins.getContactJoins())) + : null; + if (contactFilter != null) { + filter = cb.or( + filter, + CriteriaBuilderHelper + .or(cb, contactFilter, createAssigneeOrObserverFilter(cb, joins.getAssignee(), joins.getTaskObservers(), currentUser))); + } + Predicate eventFilter = hasContextOrNoContext(taskCriteria, TaskContext.EVENT) + ? eventService.createUserFilter(new EventQueryContext(cb, cq, joins.getEventJoins())) + : null; + if (eventFilter != null) { + filter = cb.or(filter, eventFilter); } Predicate travelEntryFilter = hasContextOrNoContext(taskCriteria, TaskContext.TRAVEL_ENTRY) - ? travelEntryService.createUserFilter(new TravelEntryQueryContext(cb, cq, joins.getTravelEntryJoins())) - : null; + ? travelEntryService.createUserFilter(new TravelEntryQueryContext(cb, cq, joins.getTravelEntryJoins())) + : null; if (travelEntryFilter != null) { filter = cb.or(filter, travelEntryFilter); } @@ -301,17 +254,9 @@ public Predicate createUserFilter(TaskQueryContext taskQueryContext, TaskCriteri filter = cb.or(filter, assigneeFilter); if (RequestContextHolder.isMobileSync()) { - if (obsolete) { - Predicate limitedChangeDateForObsoletePredicate = - CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilterForObsoleteEntities(cb, taskQueryContext.getRoot())); - if (limitedChangeDateForObsoletePredicate != null) { - filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDateForObsoletePredicate); - } - } else { - Predicate limitedChangeDatePredicate = CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilter(cb, taskQueryContext.getRoot())); - if (limitedChangeDatePredicate != null) { - filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDatePredicate); - } + Predicate limitedChangeDatePredicate = CriteriaBuilderHelper.and(cb, createLimitedChangeDateFilter(cb, taskQueryContext.getRoot())); + if (limitedChangeDatePredicate != null) { + filter = CriteriaBuilderHelper.and(cb, filter, limitedChangeDatePredicate); } } @@ -353,7 +298,7 @@ protected List getAdditionalObsoleteUuidsPredicates(Date since, Crite @Override protected Predicate getUserFilterForObsoleteUuids(CriteriaBuilder cb, CriteriaQuery cq, Root from) { - return createUserFilterForObsolete(new TaskQueryContext(cb, cq, from), new TaskCriteria().excludeLimitedSyncRestrictions(true)); + return createUserFilter(new TaskQueryContext(cb, cq, from), new TaskCriteria().excludeLimitedSyncRestrictions(true)); } public Predicate createAssigneeFilter(CriteriaBuilder cb, Join assigneeUserJoin) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java index 51378a07855..bf780eb3ca5 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionService.java @@ -13,7 +13,6 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; -import de.symeda.sormas.api.RequestContextHolder; import org.apache.commons.lang3.StringUtils; import de.symeda.sormas.api.therapy.PrescriptionCriteria; @@ -70,17 +69,6 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c return filter; } - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - - } - public List getAllActiveUuids(User user) { CriteriaBuilder cb = em.getCriteriaBuilder(); @@ -96,13 +84,6 @@ public List getAllActiveUuids(User user) { filter = CriteriaBuilderHelper.and(cb, filter, userFilter); } - if (RequestContextHolder.isMobileSync()) { - Predicate predicate = createLimitedChangeDateFilter(cb, from); - if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, filter, predicate); - } - } - cq.where(filter); cq.select(from.get(Prescription.UUID)); @@ -147,13 +128,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - - Join therapy = from.join(Prescription.THERAPY, JoinType.LEFT); - return caseService.createUserFilterForObsoleteSync(new CaseQueryContext(cb, cq, new CaseJoins(therapy.join(Therapy.CASE, JoinType.LEFT)))); - } - @Override public boolean inJurisdictionOrOwned(Prescription entity) { return fulfillsCondition(entity, (cb, cq, from) -> inJurisdictionOrOwned(cb, cq, from)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java index 776383bddea..f7fc9cbe839 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentService.java @@ -14,7 +14,6 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; -import de.symeda.sormas.api.RequestContextHolder; import org.apache.commons.lang3.StringUtils; import de.symeda.sormas.api.therapy.TreatmentCriteria; @@ -70,16 +69,6 @@ protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery c return filter; } - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public List getAllActiveUuids(User user) { CriteriaBuilder cb = em.getCriteriaBuilder(); @@ -95,13 +84,6 @@ public List getAllActiveUuids(User user) { filter = CriteriaBuilderHelper.and(cb, filter, userFilter); } - if (RequestContextHolder.isMobileSync()) { - Predicate predicate = createLimitedChangeDateFilter(cb, from); - if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, filter, predicate); - } - } - cq.where(filter); cq.select(from.get(Treatment.UUID)); @@ -144,13 +126,7 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - Join therapy = from.join(Treatment.THERAPY, JoinType.LEFT); - return caseService.createUserFilterForObsoleteSync(new CaseQueryContext(cb, cq, new CaseJoins(therapy.join(Therapy.CASE, JoinType.LEFT)))); - } - - public void unlinkPrescriptionFromTreatments(List treatmentUuids){ + public void unlinkPrescriptionFromTreatments(List treatmentUuids) { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaUpdate criteriaUpdate = cb.createCriteriaUpdate(getElementClass()); Root from = criteriaUpdate.from(getElementClass()); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/BaseTravelEntryService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/BaseTravelEntryService.java index 52b5b814b17..531b61e67f3 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/BaseTravelEntryService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/BaseTravelEntryService.java @@ -26,24 +26,14 @@ protected BaseTravelEntryService() { } @Override - public Predicate inJurisdictionOrOwned(CriteriaBuilder cb, CriteriaQuery query, From from) { + public Predicate inJurisdictionOrOwned(CriteriaBuilder cb, CriteriaQuery query, From from) { return inJurisdictionOrOwned(new TravelEntryQueryContext(cb, query, from)); } - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public Predicate inJurisdictionOrOwned(TravelEntryQueryContext qc) { return inJurisdictionOrOwned(qc, userService.getCurrentUser()); } - + public Predicate inJurisdictionOrOwned(TravelEntryQueryContext qc, User user) { return TravelEntryJurisdictionPredicateValidator.of(qc, user).inJurisdictionOrOwned(); } @@ -58,11 +48,6 @@ protected Predicate createUserFilterInternal(CriteriaBuilder cb, CriteriaQuery c return createUserFilter(new TravelEntryQueryContext(cb, cq, from)); } - @Override - public Predicate createUserFilterForObsoleteSync(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return createUserFilter(new TravelEntryQueryContext(cb, cq, from)); - } - public Predicate createUserFilter(TravelEntryQueryContext qc) { User currentUser = getCurrentUser(); if (currentUser == null) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserRoleService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserRoleService.java index c78723c0f79..90af64c2f5d 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserRoleService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserRoleService.java @@ -66,21 +66,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public UserRole getByCaption(String caption) { CriteriaBuilder cb = em.getCriteriaBuilder(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserService.java index ac99b403eb2..b04333e6a35 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserService.java @@ -100,16 +100,6 @@ public UserService() { super(User.class); } - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public User createUser() { User user = new User(); @@ -718,12 +708,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - // no filter by user needed - return null; - } - public Predicate createCurrentUserJurisdictionFilter(CriteriaBuilder cb, From from) { if (hasRight(UserRight.SEE_PERSONAL_DATA_OUTSIDE_JURISDICTION)) { return cb.conjunction(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/vaccination/VaccinationService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/vaccination/VaccinationService.java index d374d4c6b57..e4a88744440 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/vaccination/VaccinationService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/vaccination/VaccinationService.java @@ -79,16 +79,6 @@ public VaccinationService() { super(Vaccination.class); } - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - public Map getLastVaccinationType() { Map result = new HashMap<>(); String queryString = @@ -98,17 +88,13 @@ public Map getLastVaccinationType() { return result; } - public List getVaccinationsByCriteria( - VaccinationCriteria criteria, - Integer first, - Integer max, - List sortProperties) { + public List getVaccinationsByCriteria(VaccinationCriteria criteria, Integer first, Integer max, List sortProperties) { final CriteriaBuilder cb = em.getCriteriaBuilder(); final CriteriaQuery cq = cb.createQuery(Vaccination.class); final Root root = cq.from(Vaccination.class); - + Predicate filter = buildCriteriaFilter(criteria, cb, root); - + cq.where(filter); if (sortProperties != null && !sortProperties.isEmpty()) { @@ -369,11 +355,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return null; - } - @Override public boolean inJurisdictionOrOwned(Vaccination entity) { return fulfillsCondition(entity, this::inJurisdictionOrOwned); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java index 171e4adfb23..e9b1cb02585 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitService.java @@ -41,7 +41,6 @@ import javax.persistence.criteria.Subquery; import de.symeda.sormas.api.Disease; -import de.symeda.sormas.api.RequestContextHolder; import de.symeda.sormas.api.caze.CaseLogic; import de.symeda.sormas.api.contact.ContactLogic; import de.symeda.sormas.api.followup.FollowUpLogic; @@ -88,16 +87,6 @@ public boolean inJurisdictionOrOwned(Visit entity) { return fulfillsCondition(entity, (cb, cq, from) -> inJurisdictionOrOwned(cb, cq, from)); } - @Override - protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { - return null; - } - - @Override - protected Predicate createLimitedChangeDateFilterForObsoleteEntities(CriteriaBuilder cb, From from) { - return null; - } - @SuppressWarnings("rawtypes") private Predicate inJurisdictionOrOwned(CriteriaBuilder cb, CriteriaQuery cq, From from) { return inJurisdictionOrOwned(new VisitQueryContext(cb, cq, from)); @@ -185,12 +174,6 @@ public List getAllAfter(Date since, Integer batchSize, String lastSynchro if (since != null) { filter = CriteriaBuilderHelper.and(cb, filter, createChangeDateFilter(cb, from, since, lastSynchronizedUuid)); } - if (RequestContextHolder.isMobileSync()) { - Predicate predicate = createLimitedChangeDateFilter(cb, from); - if (predicate != null) { - filter = CriteriaBuilderHelper.and(cb, filter, predicate); - } - } return filter; }, batchSize); } @@ -200,11 +183,6 @@ public Predicate createUserFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { - return null; - } - @SuppressWarnings("rawtypes") protected Predicate createRelevantDataFilter(CriteriaBuilder cb, CriteriaQuery cq, From from) { From ad705bdc020ea82dab1df17711736c08d6f6e746 Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Wed, 4 Jan 2023 15:29:08 +0100 Subject: [PATCH 064/166] fix --- .../e2etests/pages/application/cases/CaseImportExportPage.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/CaseImportExportPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/CaseImportExportPage.java index ee3eb4bf481..8c0f13adc81 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/CaseImportExportPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/CaseImportExportPage.java @@ -41,7 +41,8 @@ public class CaseImportExportPage { By.xpath("//label[text()='District']"); public static final By NEW_EXPORT_CONFIGURATION_SAVE_BUTTON = By.id("actionSave"); public static final By CUSTOM_CASE_EXPORT_DOWNLOAD_BUTTON = - By.xpath("//div[@class='popupContent']//div[@class='v-slot v-slot-primary']"); + By.xpath( + "//div[@class='popupContent']//div[@class='v-slot v-slot-primary v-slot-caption-overflow-label']"); public static final By CUSTOM_CASE_DELETE_BUTTON = By.xpath( "//div[@class='popupContent']//div[@class='v-horizontallayout v-layout v-horizontal v-widget']//div[5]"); From 2a836c3393f015e3db1f02b8c59f2ed12a261a39 Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Thu, 5 Jan 2023 11:20:12 +0100 Subject: [PATCH 065/166] fix --- .../e2etests/pages/application/cases/CreateNewCasePage.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/CreateNewCasePage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/CreateNewCasePage.java index 0998b41c23c..7c46b20a649 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/CreateNewCasePage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/cases/CreateNewCasePage.java @@ -100,9 +100,11 @@ public class CreateNewCasePage { public static final By CASE_DOCUMENT_EMPTY_TEXT = By.xpath("//div[@location='documents']//div[@class='v-label v-widget v-label-undef-w']"); public static final By DOWNLOAD_LAST_UPDATED_CASE_DOCUMENT = - By.xpath("//div[@location='documents']//div[@class='v-button v-widget']"); + By.xpath( + "//div[@location='documents']//div[@class='v-button v-widget caption-overflow-label v-button-caption-overflow-label']"); public static final By DELETE_LAST_UPDATED_CASE_DOCUMENT = - By.xpath("(//div[@location='documents']//div[@class='v-button v-widget'])[2]"); + By.xpath( + "(//div[@location='documents']//div[@class='v-button v-widget caption-overflow-label v-button-caption-overflow-label'])[2]"); public static final By ACTION_CONFIRM_POPUP_BUTTON = By.cssSelector(".popupContent #actionConfirm"); public static final By NICKNAME_ATTRIBUTE = From 6b3a6701bd797a3ba6d383de7c93a8a8382baf7e Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Thu, 5 Jan 2023 11:46:32 +0100 Subject: [PATCH 066/166] rerunAttempts = 3 --- .../java/org/sormas/e2etests/runner/CucumberTestRunner.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/runner/CucumberTestRunner.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/runner/CucumberTestRunner.java index 52324d2bc3f..ca42a03a16a 100755 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/runner/CucumberTestRunner.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/runner/CucumberTestRunner.java @@ -29,7 +29,7 @@ runLevel = CourgetteRunLevel.SCENARIO, showTestOutput = true, rerunFailedScenarios = true, - rerunAttempts = 4, + rerunAttempts = 3, cucumberOptions = @CucumberOptions( features = "src/test/resources/features", From 616c4cfed81fa5866d1d4086ff48695b1cb6b27c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=A9=20Strysewske?= Date: Thu, 5 Jan 2023 12:22:05 +0100 Subject: [PATCH 067/166] #7305 - Fixed interfaces, added SQL migration --- .../de/symeda/sormas/backend/caze/CaseService.java | 4 ++-- .../AdoServiceWithUserFilterAndJurisdiction.java | 2 +- ...r.java => BaseLimitedChangeDateFilterProvider.java} | 8 +++++--- ...=> ImplementedLimitedChangeDateFilterProvider.java} | 8 +++----- .../symeda/sormas/backend/contact/ContactService.java | 4 ++-- .../de/symeda/sormas/backend/event/EventService.java | 4 ++-- .../backend/immunization/ImmunizationService.java | 10 ++++------ .../de/symeda/sormas/backend/task/TaskService.java | 5 +++-- .../src/main/resources/sql/sormas_schema.sql | 5 +++++ 9 files changed, 27 insertions(+), 23 deletions(-) rename sormas-backend/src/main/java/de/symeda/sormas/backend/common/{EmptyLimitedChangeDateFilterProvider.java => BaseLimitedChangeDateFilterProvider.java} (73%) rename sormas-backend/src/main/java/de/symeda/sormas/backend/common/{LimitedChangeDateFilterProvider.java => ImplementedLimitedChangeDateFilterProvider.java} (84%) 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 63156f9bb92..2fef14d09a3 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 @@ -118,7 +118,7 @@ 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.common.LimitedChangeDateFilterProvider; +import de.symeda.sormas.backend.common.ImplementedLimitedChangeDateFilterProvider; import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.contact.ContactJoins; import de.symeda.sormas.backend.contact.ContactQueryContext; @@ -181,7 +181,7 @@ @Stateless @LocalBean -public class CaseService extends AbstractCoreAdoService implements LimitedChangeDateFilterProvider { +public class CaseService extends AbstractCoreAdoService implements ImplementedLimitedChangeDateFilterProvider { private static final Double SECONDS_30_DAYS = Long.valueOf(TimeUnit.DAYS.toSeconds(30L)).doubleValue(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java index 47dc77d7818..d1911cedb5b 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java @@ -27,7 +27,7 @@ * JPA entity managed by this Service. */ public abstract class AdoServiceWithUserFilterAndJurisdiction extends BaseAdoService - implements EmptyLimitedChangeDateFilterProvider { + implements BaseLimitedChangeDateFilterProvider { public static final int NR_OF_LAST_PHONE_DIGITS_TO_SEARCH = 6; @EJB diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/EmptyLimitedChangeDateFilterProvider.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/BaseLimitedChangeDateFilterProvider.java similarity index 73% rename from sormas-backend/src/main/java/de/symeda/sormas/backend/common/EmptyLimitedChangeDateFilterProvider.java rename to sormas-backend/src/main/java/de/symeda/sormas/backend/common/BaseLimitedChangeDateFilterProvider.java index c93e851e751..de5e1207f89 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/EmptyLimitedChangeDateFilterProvider.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/BaseLimitedChangeDateFilterProvider.java @@ -4,14 +4,16 @@ import javax.persistence.criteria.From; import javax.persistence.criteria.Predicate; -public interface EmptyLimitedChangeDateFilterProvider extends LimitedChangeDateFilterProvider { +public interface BaseLimitedChangeDateFilterProvider { - @Override default Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from, boolean featureEnabled, Integer maxChangeDatePeriod) { return createEmptyLimitedChangeDateFilter(); } - @Override + default Predicate createEmptyLimitedChangeDateFilter() { + return null; + } + default boolean hasLimitedChangeDateFilterImplementation() { return false; } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/LimitedChangeDateFilterProvider.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/ImplementedLimitedChangeDateFilterProvider.java similarity index 84% rename from sormas-backend/src/main/java/de/symeda/sormas/backend/common/LimitedChangeDateFilterProvider.java rename to sormas-backend/src/main/java/de/symeda/sormas/backend/common/ImplementedLimitedChangeDateFilterProvider.java index a74104d86c8..f5815aa3700 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/LimitedChangeDateFilterProvider.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/ImplementedLimitedChangeDateFilterProvider.java @@ -9,8 +9,9 @@ import de.symeda.sormas.api.utils.DateHelper; -public interface LimitedChangeDateFilterProvider { +public interface ImplementedLimitedChangeDateFilterProvider extends BaseLimitedChangeDateFilterProvider { + @Override default Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from, boolean featureEnabled, Integer maxChangeDatePeriod) { if (featureEnabled && maxChangeDatePeriod != null && maxChangeDatePeriod >= 0) { @@ -22,10 +23,7 @@ default Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From return null; } - default Predicate createEmptyLimitedChangeDateFilter() { - return null; - } - + @Override default boolean hasLimitedChangeDateFilterImplementation() { return true; } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java index 8ccf6ce96e6..60cd70c9f22 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java @@ -96,8 +96,8 @@ 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.common.ImplementedLimitedChangeDateFilterProvider; import de.symeda.sormas.backend.common.JurisdictionFlagsService; -import de.symeda.sormas.backend.common.LimitedChangeDateFilterProvider; import de.symeda.sormas.backend.contact.transformers.ContactListEntryDtoResultTransformer; import de.symeda.sormas.backend.disease.DiseaseConfigurationFacadeEjb.DiseaseConfigurationFacadeEjbLocal; import de.symeda.sormas.backend.document.DocumentService; @@ -140,7 +140,7 @@ @LocalBean public class ContactService extends AbstractCoreAdoService implements JurisdictionFlagsService, - LimitedChangeDateFilterProvider { + ImplementedLimitedChangeDateFilterProvider { @EJB private CaseService caseService; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java index 3e8db27c06d..a27dc082869 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java @@ -74,7 +74,7 @@ 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.common.LimitedChangeDateFilterProvider; +import de.symeda.sormas.backend.common.ImplementedLimitedChangeDateFilterProvider; import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.document.DocumentService; import de.symeda.sormas.backend.externalsurveillancetool.ExternalSurveillanceToolGatewayFacadeEjb; @@ -107,7 +107,7 @@ @Stateless @LocalBean -public class EventService extends AbstractCoreAdoService implements LimitedChangeDateFilterProvider { +public class EventService extends AbstractCoreAdoService implements ImplementedLimitedChangeDateFilterProvider { @EJB private EventParticipantService eventParticipantService; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java index 61b7bf1c84f..2e774acb2cd 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java @@ -54,7 +54,7 @@ import de.symeda.sormas.backend.common.ChangeDateBuilder; import de.symeda.sormas.backend.common.ChangeDateFilterBuilder; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; -import de.symeda.sormas.backend.common.LimitedChangeDateFilterProvider; +import de.symeda.sormas.backend.common.ImplementedLimitedChangeDateFilterProvider; import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.immunization.entity.DirectoryImmunization; import de.symeda.sormas.backend.immunization.entity.Immunization; @@ -79,7 +79,8 @@ @Stateless @LocalBean -public class ImmunizationService extends AbstractCoreAdoService implements LimitedChangeDateFilterProvider { +public class ImmunizationService extends AbstractCoreAdoService + implements ImplementedLimitedChangeDateFilterProvider { @EJB private PersonService personService; @@ -200,10 +201,7 @@ public Predicate createChangeDateFilter(CriteriaBuilder cb, From> T addChangeDates( - T builder, - ImmunizationJoins joins, - boolean includeExtendedChangeDateFilters) { + protected > T addChangeDates(T builder, ImmunizationJoins joins, boolean includeExtendedChangeDateFilters) { From immunizationFrom = joins.getRoot(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java index bd331e89ca8..0642f19244d 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java @@ -67,8 +67,8 @@ import de.symeda.sormas.backend.common.AbstractDomainObject; import de.symeda.sormas.backend.common.AdoServiceWithUserFilterAndJurisdiction; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; +import de.symeda.sormas.backend.common.ImplementedLimitedChangeDateFilterProvider; import de.symeda.sormas.backend.common.JurisdictionFlagsService; -import de.symeda.sormas.backend.common.LimitedChangeDateFilterProvider; import de.symeda.sormas.backend.common.TaskCreationException; import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.contact.ContactQueryContext; @@ -91,7 +91,8 @@ @Stateless @LocalBean public class TaskService extends AdoServiceWithUserFilterAndJurisdiction - implements JurisdictionFlagsService, LimitedChangeDateFilterProvider { + implements JurisdictionFlagsService, + ImplementedLimitedChangeDateFilterProvider { @EJB private CaseService caseService; diff --git a/sormas-backend/src/main/resources/sql/sormas_schema.sql b/sormas-backend/src/main/resources/sql/sormas_schema.sql index fea9bca0898..c5b5e4ce94e 100644 --- a/sormas-backend/src/main/resources/sql/sormas_schema.sql +++ b/sormas-backend/src/main/resources/sql/sormas_schema.sql @@ -12256,4 +12256,9 @@ INSERT INTO userroles_userrights (userrole_id, userright) SELECT id, 'TASK_ARCHI INSERT INTO schema_version (version_number, comment) VALUES (504, 'Add task archive user right #4060'); +-- 2023-01-05 Add max change date period property to limited synchronization feature #7305 +UPDATE featureconfiguration SET properties = properties::jsonb || json_build_object('MAX_CHANGE_DATE_PERIOD',-1)::jsonb WHERE featuretype = 'LIMITED_SYNCHRONIZATION'; + +INSERT INTO schema_version (version_number, comment) VALUES (505, 'Add max change date period property to limited synchronization feature #7305'); + -- *** Insert new sql commands BEFORE this line. Remember to always consider _history tables. *** From be1b62f60c013b2e96e236fbc8703afa21e6ddd7 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Thu, 5 Jan 2023 14:36:03 +0100 Subject: [PATCH 068/166] fixes in date format --- .../e2etests/steps/web/application/cases/EditCaseSteps.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java index 9a2b3fdf4e7..887039fadac 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 @@ -1954,7 +1954,7 @@ public EditCaseSteps( softly.assertEquals( webDriverHelpers.getValueFromWebElement(POINT_OF_ENTRY_DETAILS), "Automated test dummy description " - + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-M-dd")), + + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")), "Point of entry details are not correct"); softly.assertAll(); From abdaabe448185dfebcd34f8166f08f1a2328a7b6 Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Thu, 5 Jan 2023 14:47:51 +0100 Subject: [PATCH 069/166] fix --- .../steps/web/application/samples/CreateNewSampleSteps.java | 1 + 1 file changed, 1 insertion(+) 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 889fec6c359..02a43d5a6d2 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 @@ -375,6 +375,7 @@ public CreateNewSampleSteps( When( "^I validate the existence of two pathogen tests", () -> { + TimeUnit.SECONDS.sleep(2); softly.assertEquals( webDriverHelpers.getNumberOfElements(EDIT_PATHOGEN_TEST), 2, From 54451329acce97491faa04b6ac943b0752401b8e Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Thu, 5 Jan 2023 15:40:50 +0100 Subject: [PATCH 070/166] fix --- .../src/test/resources/features/sanity/web/Login.feature | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Login.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Login.feature index 9ee75345df2..12830bf7e1c 100755 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Login.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Login.feature @@ -1,7 +1,7 @@ @UI @Sanity @Login @precon Feature: Login with different type of users - @env_main @LoginMain + @env_main @LoginMain @testIt Scenario Outline: Login with user on Main Environment Given I navigate to SORMAS login page And I check that Login page is correctly displayed in English language @@ -15,7 +15,7 @@ Feature: Login with different type of users Examples: | user | | National User | - | National Language User | +# | National Language User | | Contact Supervisor | | Surveillance Officer | | Surveillance Supervisor | @@ -45,7 +45,7 @@ Feature: Login with different type of users Examples: | user | | National User | - | National Language User | +# | National Language User | | Contact Supervisor | | Surveillance Officer | | Surveillance Supervisor | From 8a4a87116695664e734643fad26bf4706b33d8df Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Thu, 5 Jan 2023 15:41:16 +0100 Subject: [PATCH 071/166] fix --- .../src/test/resources/features/sanity/web/Login.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Login.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Login.feature index 12830bf7e1c..93fa4eaa509 100755 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Login.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Login.feature @@ -70,7 +70,7 @@ Feature: Login with different type of users Examples: | user | | Admin User | - | National User | + # | National User | @env_keycloak @LoginKeycloak Scenario: Login on Keycloak Administrator Console From c930648d98491248350f64dd08e4e6c2c7b559a3 Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Fri, 6 Jan 2023 10:15:32 +0200 Subject: [PATCH 072/166] #11017 - Persons with incomplete home addresses from different jurisdictions can not be merged --- .../de/symeda/sormas/api/i18n/Strings.java | 1 + .../src/main/resources/strings.properties | 1 + .../backend/person/PersonFacadeEjb.java | 72 ++++-- .../symeda/sormas/backend/util/DtoHelper.java | 128 ++++++----- .../backend/person/PersonFacadeEjbTest.java | 211 +++++++++++++++++- 5 files changed, 336 insertions(+), 77 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java index 14083abf1f8..ac9db4144f1 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 @@ -1185,6 +1185,7 @@ public interface Strings { String messagePersonAlreadyEventParticipant = "messagePersonAlreadyEventParticipant"; String messagePersonContactDetailsPrimaryDuplicate = "messagePersonContactDetailsPrimaryDuplicate"; String messagePersonExternalTokenWarning = "messagePersonExternalTokenWarning"; + String messagePersonMergedAddressDescription = "messagePersonMergedAddressDescription"; String messagePersonSaved = "messagePersonSaved"; String messagePersonSavedClassificationChanged = "messagePersonSavedClassificationChanged"; String messagePlagueTypeChange = "messagePlagueTypeChange"; diff --git a/sormas-api/src/main/resources/strings.properties b/sormas-api/src/main/resources/strings.properties index 6fc10c29777..6e4335396ac 100644 --- a/sormas-api/src/main/resources/strings.properties +++ b/sormas-api/src/main/resources/strings.properties @@ -1113,6 +1113,7 @@ messagePathogenTestSavedShort = Pathogen test saved messagePathogenTestsDeleted = All selected pathogen tests have been deleted messagePersonSaved = Person data saved messagePersonSavedClassificationChanged = Person data saved. The classification of at least one case associated with this person was automatically changed to %s. +messagePersonMergedAddressDescription = Adopted from discarded person during merge messagePlagueTypeChange = The symptoms selected match the clinical criteria for %s. The plague type is set to %s for this case. messagePrescriptionCreated = Prescription created messagePrescriptionSaved = Prescription saved diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java index e6a249bcef2..a9459ecf917 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java @@ -95,6 +95,7 @@ import de.symeda.sormas.api.person.ApproximateAgeType.ApproximateAgeHelper; import de.symeda.sormas.api.person.CauseOfDeath; import de.symeda.sormas.api.person.JournalPersonDto; +import de.symeda.sormas.api.person.PersonAddressType; import de.symeda.sormas.api.person.PersonAssociation; import de.symeda.sormas.api.person.PersonContactDetailDto; import de.symeda.sormas.api.person.PersonContactDetailType; @@ -1787,13 +1788,15 @@ public void mergePerson(PersonDto leadPerson, PersonDto otherPerson) { } } - DtoHelper.copyDtoValues(leadPerson, otherPerson, false); + DtoHelper.copyDtoValues(leadPerson, otherPerson, false, PersonDto.ADDRESS); + processPersonAddressMerge(leadPerson, otherPerson); + save(leadPerson); } @Override @RightsAllowed(UserRight._PERSON_EDIT) - public void mergePerson(String leadPersonUuid, String otherPersonUuid, boolean mergeProperties) throws CloneNotSupportedException { + public void mergePerson(String leadPersonUuid, String otherPersonUuid, boolean mergeProperties) { if (leadPersonUuid.equals(otherPersonUuid)) { throw new UnsupportedOperationException("Two different persons need to be selected for merge!"); @@ -1816,14 +1819,8 @@ public void mergePerson(String leadPersonUuid, String otherPersonUuid, boolean m } } - LocationDto leadPersonAddress = (LocationDto) leadPersonDto.getAddress().clone(); - LocationDto otherPersonAddress = otherPersonDto.getAddress(); - DtoHelper.copyDtoValues(leadPersonDto, otherPersonDto, false); - - if (differentLocation(leadPersonAddress, otherPersonAddress)) { - leadPersonDto.setAddress(leadPersonAddress); - leadPersonDto.addAddress(otherPersonAddress); - } + DtoHelper.copyDtoValues(leadPersonDto, otherPersonDto, false, PersonDto.ADDRESS); + processPersonAddressMerge(leadPersonDto, otherPersonDto); save(leadPersonDto); } @@ -1867,11 +1864,58 @@ public void mergePerson(String leadPersonUuid, String otherPersonUuid, boolean m service.ensurePersisted(leadPerson); } + private void processPersonAddressMerge(PersonDto leadPersonDto, PersonDto otherPersonDto) { + if (differentLocation(leadPersonDto.getAddress(), otherPersonDto.getAddress())) { + LocationDto otherAddress = otherPersonDto.getAddress(); + otherAddress.setAddressType(PersonAddressType.OTHER_ADDRESS); + otherAddress.setAddressTypeDetails(I18nProperties.getString(Strings.messagePersonMergedAddressDescription)); + leadPersonDto.addAddress(otherPersonDto.getAddress()); + } else { + DtoHelper.copyDtoValues(leadPersonDto.getAddress(), otherPersonDto.getAddress(), false); + } + } + private boolean differentLocation(LocationDto firstAddress, LocationDto secondAddress) { - return firstAddress.getCountry() != secondAddress.getCountry() - || firstAddress.getRegion() != secondAddress.getRegion() - || firstAddress.getDistrict() != secondAddress.getDistrict() - || firstAddress.getCommunity() != secondAddress.getCommunity(); + if (firstAddress.getCountry() != null && !firstAddress.getCountry().getUuid().equals(secondAddress.getCountry().getUuid())) { + return true; + } + + if (firstAddress.getRegion() != null && !firstAddress.getRegion().getUuid().equals(secondAddress.getRegion().getUuid())) { + return true; + } + + if (firstAddress.getDistrict() != null && !firstAddress.getDistrict().getUuid().equals(secondAddress.getDistrict().getUuid())) { + return true; + } + + if (firstAddress.getCommunity() != null && !firstAddress.getCommunity().getUuid().equals(secondAddress.getCommunity().getUuid())) { + return true; + } + + if (firstAddress.getFacility() != null) { + FacilityDto firstAddressFacilityDto = facilityFacade.getByUuid(firstAddress.getFacility().getUuid()); + if (secondAddress.getCommunity() != null + && !firstAddressFacilityDto.getCommunity().getUuid().equals(secondAddress.getCommunity().getUuid())) { + return true; + } + } + + if (firstAddress.getCity() != null && !firstAddress.getCity().equals(secondAddress.getCity())) { + return true; + } + + if (firstAddress.getPostalCode() != null && !firstAddress.getPostalCode().equals(secondAddress.getPostalCode())) { + return true; + } + + if (firstAddress.getStreet() != null && !firstAddress.getStreet().equals(secondAddress.getStreet())) { + return true; + } + + if (firstAddress.getHouseNumber() != null && !firstAddress.getHouseNumber().equals(secondAddress.getHouseNumber())) { + return true; + } + return false; } @Override diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/util/DtoHelper.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/util/DtoHelper.java index d61e8c3571f..e2919607c7e 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/util/DtoHelper.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/util/DtoHelper.java @@ -22,6 +22,7 @@ import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.sql.Timestamp; +import java.util.Arrays; import java.util.Collection; import java.util.EnumMap; import java.util.Map; @@ -66,6 +67,10 @@ public static void fillDto(EntityDto dto, AbstractDomainObject entity) { dto.setUuid(entity.getUuid()); } + public static T copyDtoValues(T target, T source, boolean overrideValues) { + return copyDtoValues(target, source, overrideValues, null); + } + /** * @param overrideValues * Note: Existing references are NOT overridden @@ -73,7 +78,7 @@ public static void fillDto(EntityDto dto, AbstractDomainObject entity) { @SuppressWarnings({ "unchecked", "rawtypes" }) - public static T copyDtoValues(T target, T source, boolean overrideValues) { + public static T copyDtoValues(T target, T source, boolean overrideValues, String... skippedFields) { try { PropertyDescriptor[] pds = Introspector.getBeanInfo(target.getClass(), EntityDto.class).getPropertyDescriptors(); @@ -91,78 +96,81 @@ public static T copyDtoValues(T target, T source, boolean continue; } - if (EntityDto.class.isAssignableFrom(pd.getPropertyType())) { - - if (targetValue == null) { - targetValue = sourceValue.getClass().newInstance(); - pd.getWriteMethod().invoke(target, targetValue); - } - - // If both entities have the same UUID, assign a new one to targetValue to create a new entity - if (((EntityDto) targetValue).getUuid().equals(((EntityDto) sourceValue).getUuid())) { - ((EntityDto) targetValue).setUuid(DataHelper.createUuid()); - } - - // entity: just fill the existing one with the source - copyDtoValues((EntityDto) targetValue, (EntityDto) sourceValue, overrideValues); - } else { - boolean override = overrideValues && !ReferenceDto.class.isAssignableFrom(pd.getPropertyType()); - // should we write into the target property? - if (Collection.class.isAssignableFrom(pd.getPropertyType())) { + if (skippedFields == null || Arrays.stream(skippedFields).noneMatch(field -> field.equals(pd.getName()))) { + if (EntityDto.class.isAssignableFrom(pd.getPropertyType())) { if (targetValue == null) { targetValue = sourceValue.getClass().newInstance(); pd.getWriteMethod().invoke(target, targetValue); } - Collection targetCollection = (Collection) targetValue; - - for (Object sourceEntry : (Collection) sourceValue) { - if (sourceEntry instanceof EntityDto) { - EntityDto newEntry = ((EntityDto) sourceEntry).clone(); - newEntry.setUuid(DataHelper.createUuid()); - newEntry.setCreationDate(null); - copyDtoValues(newEntry, (EntityDto) sourceEntry, true); - targetCollection.add(newEntry); - } else if (DataHelper.isValueType(sourceEntry.getClass()) - || sourceEntry instanceof ReferenceDto - || sourceEntry instanceof JsonDataEntry) { - targetCollection.add(sourceEntry); - } else { - throw new UnsupportedOperationException(pd.getPropertyType().getName() + " is not supported as a list entry type."); - } + // If both entities have the same UUID, assign a new one to targetValue to create a new entity + if (((EntityDto) targetValue).getUuid().equals(((EntityDto) sourceValue).getUuid())) { + ((EntityDto) targetValue).setUuid(DataHelper.createUuid()); } - } else if (Map.class.isAssignableFrom(pd.getPropertyType())) { - if (targetValue == null) { - if (sourceValue.getClass() == EnumMap.class) { - // Enum map needs to be initialized with the content of the source map because it does not have an init method - targetValue = Maps.newEnumMap((EnumMap) sourceValue); - ((EnumMap) targetValue).clear(); - } else { + // entity: just fill the existing one with the source + copyDtoValues((EntityDto) targetValue, (EntityDto) sourceValue, overrideValues); + } else { + boolean override = overrideValues && !ReferenceDto.class.isAssignableFrom(pd.getPropertyType()); + // should we write into the target property? + if (Collection.class.isAssignableFrom(pd.getPropertyType())) { + + if (targetValue == null) { targetValue = sourceValue.getClass().newInstance(); + pd.getWriteMethod().invoke(target, targetValue); } - pd.getWriteMethod().invoke(target, targetValue); - } - Map targetMap = (Map) targetValue; + Collection targetCollection = (Collection) targetValue; + + for (Object sourceEntry : (Collection) sourceValue) { + if (sourceEntry instanceof EntityDto) { + EntityDto newEntry = ((EntityDto) sourceEntry).clone(); + newEntry.setUuid(DataHelper.createUuid()); + newEntry.setCreationDate(null); + copyDtoValues(newEntry, (EntityDto) sourceEntry, true); + targetCollection.add(newEntry); + } else if (DataHelper.isValueType(sourceEntry.getClass()) + || sourceEntry instanceof ReferenceDto + || sourceEntry instanceof JsonDataEntry) { + targetCollection.add(sourceEntry); + } else { + throw new UnsupportedOperationException( + pd.getPropertyType().getName() + " is not supported as a list entry type."); + } + } + } else if (Map.class.isAssignableFrom(pd.getPropertyType())) { + + if (targetValue == null) { + if (sourceValue.getClass() == EnumMap.class) { + // Enum map needs to be initialized with the content of the source map because it does not have an init method + targetValue = Maps.newEnumMap((EnumMap) sourceValue); + ((EnumMap) targetValue).clear(); + } else { + targetValue = sourceValue.getClass().newInstance(); + } + pd.getWriteMethod().invoke(target, targetValue); + } + + Map targetMap = (Map) targetValue; - for (Object sourceKey : ((Map) sourceValue).keySet()) { - if (override || !targetMap.containsKey(sourceKey)) { - targetMap.put(sourceKey, ((Map) sourceValue).get(sourceKey)); + for (Object sourceKey : ((Map) sourceValue).keySet()) { + if (override || !targetMap.containsKey(sourceKey)) { + targetMap.put(sourceKey, ((Map) sourceValue).get(sourceKey)); + } + } + } else if (targetValue == null + || override + || (pd.getPropertyType().equals(String.class) + && StringUtils.isBlank((String) targetValue) + && StringUtils.isNotBlank((String) sourceValue)) + || (pd.getPropertyType().equals(boolean.class) && ((boolean) sourceValue) && !((boolean) targetValue))) { + if (DataHelper.isValueType(pd.getPropertyType()) || ReferenceDto.class.isAssignableFrom(pd.getPropertyType())) { + pd.getWriteMethod().invoke(target, sourceValue); + } else { + // Other objects are not supported + throw new UnsupportedOperationException(pd.getPropertyType().getName() + " is not supported as a property type."); } - } - } else if (targetValue == null - || override - || (pd.getPropertyType().equals(String.class) - && StringUtils.isBlank((String) targetValue) - && StringUtils.isNotBlank((String) sourceValue)) - || (pd.getPropertyType().equals(boolean.class) && ((boolean) sourceValue) && !((boolean) targetValue))) { - if (DataHelper.isValueType(pd.getPropertyType()) || ReferenceDto.class.isAssignableFrom(pd.getPropertyType())) { - pd.getWriteMethod().invoke(target, sourceValue); - } else { - // Other objects are not supported - throw new UnsupportedOperationException(pd.getPropertyType().getName() + " is not supported as a property type."); } } } diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/person/PersonFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/person/PersonFacadeEjbTest.java index 127625a11a0..2f7e2755049 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/person/PersonFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/person/PersonFacadeEjbTest.java @@ -15,6 +15,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; @@ -38,15 +39,19 @@ import de.symeda.sormas.api.event.EventDto; import de.symeda.sormas.api.event.EventParticipantDto; import de.symeda.sormas.api.externalsurveillancetool.ExternalSurveillanceToolRuntimeException; +import de.symeda.sormas.api.i18n.I18nProperties; +import de.symeda.sormas.api.i18n.Strings; import de.symeda.sormas.api.immunization.ImmunizationDto; import de.symeda.sormas.api.immunization.ImmunizationManagementStatus; import de.symeda.sormas.api.immunization.ImmunizationStatus; import de.symeda.sormas.api.immunization.MeansOfImmunization; 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.infrastructure.region.RegionReferenceDto; import de.symeda.sormas.api.location.LocationDto; import de.symeda.sormas.api.person.JournalPersonDto; +import de.symeda.sormas.api.person.PersonAddressType; import de.symeda.sormas.api.person.PersonAssociation; import de.symeda.sormas.api.person.PersonContactDetailDto; import de.symeda.sormas.api.person.PersonContactDetailType; @@ -78,6 +83,10 @@ import de.symeda.sormas.backend.TestDataCreator; import de.symeda.sormas.backend.TestDataCreator.RDCF; import de.symeda.sormas.backend.common.ConfigFacadeEjb; +import de.symeda.sormas.backend.infrastructure.community.Community; +import de.symeda.sormas.backend.infrastructure.district.District; +import de.symeda.sormas.backend.infrastructure.facility.Facility; +import de.symeda.sormas.backend.infrastructure.region.Region; import de.symeda.sormas.backend.user.User; public class PersonFacadeEjbTest extends AbstractBeanTest { @@ -919,7 +928,7 @@ public void testMergePersonWithoutVaccinationWithPersonWithoutVaccination() { } @Test - public void testMergePersonsAndRemoveDuplication() throws CloneNotSupportedException { + public void testMergePersonsAndRemoveDuplication() { PersonDto leadPerson = creator.createPerson("John", "Doe", Sex.MALE, 1980, 1, 1, "000111222", null); PersonDto otherPerson = creator.createPerson("James", "Smith", Sex.MALE, 1990, 1, 1, "444555666", "123456789"); @@ -931,6 +940,8 @@ public void testMergePersonsAndRemoveDuplication() throws CloneNotSupportedExcep TestDataCreator.RDCFEntities rdcf1 = creator.createRDCFEntities("Region", "District", "Community", "Facility"); TestDataCreator.RDCFEntities rdcf2 = creator.createRDCFEntities("Region2", "District2", "Community2", "Facility2"); + TestDataCreator.RDCFEntities rdcf3 = creator.createRDCFEntities("Region3", "District3", "Community3", "Facility3"); + TestDataCreator.RDCFEntities rdcf4 = creator.createRDCFEntities("Region4", "District4", "Community4", "Facility4"); LocationDto leadPersonAddress = leadPerson.getAddress(); leadPersonAddress.setRegion(new RegionReferenceDto(rdcf1.region.getUuid())); @@ -941,7 +952,19 @@ public void testMergePersonsAndRemoveDuplication() throws CloneNotSupportedExcep otherPersonAddress.setDistrict(new DistrictReferenceDto(rdcf2.district.getUuid())); otherPersonAddress.setCommunity(new CommunityReferenceDto(rdcf2.community.getUuid())); - leadPerson.setAddresses(Collections.singletonList(LocationDto.build())); + List leadAddresses = new ArrayList<>(); + LocationDto leadAddresses1 = LocationDto.build(); + leadAddresses1.setRegion(new RegionReferenceDto(rdcf3.region.getUuid())); + leadAddresses1.setDistrict(new DistrictReferenceDto(rdcf3.district.getUuid())); + leadAddresses1.setCommunity(new CommunityReferenceDto(rdcf3.community.getUuid())); + leadAddresses.add(leadAddresses1); + + LocationDto leadAddresses2 = LocationDto.build(); + leadAddresses2.setRegion(new RegionReferenceDto(rdcf4.region.getUuid())); + leadAddresses2.setDistrict(new DistrictReferenceDto(rdcf4.district.getUuid())); + leadAddresses.add(leadAddresses2); + + leadPerson.setAddresses(leadAddresses); leadPerson.setAddress(leadPersonAddress); otherPerson.setAddress(otherPersonAddress); @@ -976,7 +999,7 @@ public void testMergePersonsAndRemoveDuplication() throws CloneNotSupportedExcep assertEquals(1, getVisitService().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); assertEquals(1, leadPerson.getAllEmailAddresses().size()); assertEquals(1, leadPerson.getAllPhoneNumbers().size()); - assertEquals(1, leadPerson.getAddresses().size()); + assertEquals(2, leadPerson.getAddresses().size()); assertTrue(getPersonFacade().exists(otherPerson.getUuid())); getPersonFacade().mergePerson(leadPerson.getUuid(), otherPerson.getUuid(), true); @@ -995,10 +1018,192 @@ public void testMergePersonsAndRemoveDuplication() throws CloneNotSupportedExcep List leadPersonAllPhoneNumbers = leadPerson.getAllPhoneNumbers(); assertEquals(2, leadPersonAllPhoneNumbers.size()); assertEquals(1, leadPersonAllPhoneNumbers.stream().filter(s -> s.equals("+496211218490")).count()); + assertEquals(rdcf1.region.getUuid(), leadPerson.getAddress().getRegion().getUuid()); + assertNull(leadPerson.getAddress().getCommunity()); + assertEquals(3, leadPerson.getAddresses().size()); + assertEquals(1, leadPerson.getAddresses().stream().filter(field -> field.getUuid().equals(leadAddresses1.getUuid())).count()); + assertEquals(1, leadPerson.getAddresses().stream().filter(field -> field.getUuid().equals(leadAddresses2.getUuid())).count()); + assertEquals(1, leadPerson.getAddresses().stream().filter(field -> otherPersonAddress.getDistrict().equals(field.getDistrict())).count()); + assertFalse(getPersonFacade().exists(otherPerson.getUuid())); + } + + @Test + public void testMergePersonsSameMainAddress() { + + PersonDto leadPerson = creator.createPerson("John", "Doe", Sex.MALE, 1980, 1, 1, "000111222", null); + PersonDto otherPerson = creator.createPerson("James", "Smith", Sex.MALE, 1990, 1, 1, "444555666", "123456789"); + + leadPerson.setPhone("+496211218490"); + otherPerson.setPhone("+496211218491"); + leadPerson.setEmailAddress("lead@hotmail.com"); + otherPerson.setEmailAddress("other@yahoo.com"); + + TestDataCreator.RDCFEntities rdcf1 = creator.createRDCFEntities("Region", "District", "Community", "Facility"); + TestDataCreator.RDCFEntities rdcf3 = creator.createRDCFEntities("Region3", "District3", "Community3", "Facility3"); + TestDataCreator.RDCFEntities rdcf4 = creator.createRDCFEntities("Region4", "District4", "Community4", "Facility4"); + + LocationDto leadPersonAddress = leadPerson.getAddress(); + leadPersonAddress.setRegion(new RegionReferenceDto(rdcf1.region.getUuid())); + leadPersonAddress.setDistrict(new DistrictReferenceDto(rdcf1.district.getUuid())); + + LocationDto otherPersonAddress = otherPerson.getAddress(); + otherPersonAddress.setRegion(new RegionReferenceDto(rdcf1.region.getUuid())); + otherPersonAddress.setDistrict(new DistrictReferenceDto(rdcf1.district.getUuid())); + otherPersonAddress.setCommunity(new CommunityReferenceDto(rdcf1.community.getUuid())); + + List leadAddresses = new ArrayList<>(); + LocationDto leadAddresses1 = LocationDto.build(); + leadAddresses1.setRegion(new RegionReferenceDto(rdcf3.region.getUuid())); + leadAddresses1.setDistrict(new DistrictReferenceDto(rdcf3.district.getUuid())); + leadAddresses1.setCommunity(new CommunityReferenceDto(rdcf3.community.getUuid())); + leadAddresses.add(leadAddresses1); + + LocationDto leadAddresses2 = LocationDto.build(); + leadAddresses2.setRegion(new RegionReferenceDto(rdcf4.region.getUuid())); + leadAddresses2.setDistrict(new DistrictReferenceDto(rdcf4.district.getUuid())); + leadAddresses.add(leadAddresses2); + + leadPerson.setAddresses(leadAddresses); + leadPerson.setAddress(leadPersonAddress); + otherPerson.setAddress(otherPersonAddress); + + leadPerson = getPersonFacade().save(leadPerson); + otherPerson = getPersonFacade().save(otherPerson); + + final PersonReferenceDto leadPersonRef = leadPerson.toReference(); + final PersonReferenceDto otherPersonRef = otherPerson.toReference(); + final UserReferenceDto natUserRef = nationalUser.toReference(); + + final CaseDataDto leadCase = creator.createCase(natUserRef, leadPersonRef, rdcfEntities); + creator.createContact(natUserRef, leadPersonRef); + final EventDto leadEvent = creator.createEvent(natUserRef); + creator.createEventParticipant(leadEvent.toReference(), leadPerson, natUserRef); + creator.createVisit(leadPersonRef); + creator.createImmunization(Disease.CORONAVIRUS, leadPersonRef, natUserRef, rdcf); + creator.createTravelEntry(leadPersonRef, natUserRef, rdcf, te -> te.setResultingCase(leadCase.toReference())); + + final CaseDataDto otherCase = creator.createCase(natUserRef, otherPersonRef, rdcfEntities); + creator.createContact(natUserRef, otherPersonRef); + final EventDto otherEvent = creator.createEvent(natUserRef); + creator.createEventParticipant(otherEvent.toReference(), otherPerson, natUserRef); + creator.createVisit(otherPersonRef); + creator.createImmunization(Disease.CORONAVIRUS, otherPersonRef, natUserRef, rdcf); + creator.createTravelEntry(otherPersonRef, natUserRef, rdcf, te -> te.setResultingCase(otherCase.toReference())); + + assertEquals(1, getCaseFacade().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(1, getContactFacade().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(1, getEventParticipantFacade().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(1, getImmunizationFacade().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(1, getTravelEntryFacade().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(1, getVisitService().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(1, leadPerson.getAllEmailAddresses().size()); + assertEquals(1, leadPerson.getAllPhoneNumbers().size()); + assertEquals(2, leadPerson.getAddresses().size()); + assertTrue(getPersonFacade().exists(otherPerson.getUuid())); + assertNull(leadPerson.getAddress().getCommunity()); + + getPersonFacade().mergePerson(leadPerson.getUuid(), otherPerson.getUuid(), true); + + leadPerson = getPersonFacade().getByUuid(leadPerson.getUuid()); + + assertEquals(2, getCaseFacade().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(2, getContactFacade().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(2, getEventParticipantFacade().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(2, getImmunizationFacade().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(2, getTravelEntryFacade().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(2, getVisitService().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + + assertNotNull(leadPerson.getAddress().getCommunity()); assertEquals(2, leadPerson.getAddresses().size()); assertFalse(getPersonFacade().exists(otherPerson.getUuid())); } + @Test + public void testMergePersonsLeadPersonFacilityNotMatchInfrastructureDataFromOtherPerson() { + PersonDto leadPerson = creator.createPerson("John", "Doe", Sex.MALE, 1980, 1, 1, "000111222", null); + PersonDto otherPerson = creator.createPerson("James", "Smith", Sex.MALE, 1990, 1, 1, "444555666", "123456789"); + + leadPerson.setPhone("+496211218490"); + otherPerson.setPhone("+496211218491"); + leadPerson.setEmailAddress("lead@hotmail.com"); + otherPerson.setEmailAddress("other@yahoo.com"); + + Region region = creator.createRegion("Region"); + District district = creator.createDistrict("District", region); + Community community1 = creator.createCommunity("Community1", district); + Facility facility1 = creator.createFacility("Facility1", region, district, community1); + Community community2 = creator.createCommunity("Community2", district); + Facility facility2 = creator.createFacility("Facility2", region, district, community2); + + TestDataCreator.RDCFEntities rdcf1 = new TestDataCreator.RDCFEntities(region, district, community1, facility1); + TestDataCreator.RDCFEntities rdcf2 = new TestDataCreator.RDCFEntities(region, district, community2, facility2); + TestDataCreator.RDCFEntities rdcf3 = creator.createRDCFEntities("Region3", "District3", "Community3", "Facility3"); + TestDataCreator.RDCFEntities rdcf4 = creator.createRDCFEntities("Region4", "District4", "Community4", "Facility4"); + + LocationDto leadPersonAddress = leadPerson.getAddress(); + leadPersonAddress.setRegion(new RegionReferenceDto(rdcf1.region.getUuid())); + leadPersonAddress.setDistrict(new DistrictReferenceDto(rdcf1.district.getUuid())); + leadPersonAddress.setFacility(new FacilityReferenceDto(rdcf1.facility.getUuid())); + + LocationDto otherPersonAddress = otherPerson.getAddress(); + otherPersonAddress.setRegion(new RegionReferenceDto(rdcf2.region.getUuid())); + otherPersonAddress.setDistrict(new DistrictReferenceDto(rdcf2.district.getUuid())); + otherPersonAddress.setCommunity(new CommunityReferenceDto(rdcf2.community.getUuid())); + + List leadAddresses = new ArrayList<>(); + LocationDto leadAddresses1 = LocationDto.build(); + leadAddresses1.setRegion(new RegionReferenceDto(rdcf3.region.getUuid())); + leadAddresses1.setDistrict(new DistrictReferenceDto(rdcf3.district.getUuid())); + leadAddresses1.setCommunity(new CommunityReferenceDto(rdcf3.community.getUuid())); + leadAddresses.add(leadAddresses1); + + LocationDto leadAddresses2 = LocationDto.build(); + leadAddresses2.setRegion(new RegionReferenceDto(rdcf4.region.getUuid())); + leadAddresses2.setDistrict(new DistrictReferenceDto(rdcf4.district.getUuid())); + leadAddresses.add(leadAddresses2); + + leadPerson.setAddresses(leadAddresses); + leadPerson.setAddress(leadPersonAddress); + otherPerson.setAddress(otherPersonAddress); + + leadPerson = getPersonFacade().save(leadPerson); + otherPerson = getPersonFacade().save(otherPerson); + + assertEquals(1, leadPerson.getAllEmailAddresses().size()); + assertEquals(1, leadPerson.getAllPhoneNumbers().size()); + assertEquals(2, leadPerson.getAddresses().size()); + assertTrue(getPersonFacade().exists(otherPerson.getUuid())); + assertNull(leadPerson.getAddress().getCommunity()); + + getPersonFacade().mergePerson(leadPerson.getUuid(), otherPerson.getUuid(), true); + + leadPerson = getPersonFacade().getByUuid(leadPerson.getUuid()); + + assertEquals(3, leadPerson.getAddresses().size()); + assertEquals(rdcf1.region.getUuid(), leadPerson.getAddress().getRegion().getUuid()); + assertEquals(rdcf1.district.getUuid(), leadPerson.getAddress().getDistrict().getUuid()); + assertNull(leadPerson.getAddress().getCommunity()); + assertEquals(1, leadPerson.getAddresses().stream().filter(field -> field.getUuid().equals(leadAddresses1.getUuid())).count()); + assertEquals(1, leadPerson.getAddresses().stream().filter(field -> field.getUuid().equals(leadAddresses2.getUuid())).count()); + assertEquals(1, leadPerson.getAddresses().stream().filter(field -> otherPersonAddress.getCommunity().equals(field.getCommunity())).count()); + assertEquals( + PersonAddressType.OTHER_ADDRESS, + leadPerson.getAddresses() + .stream() + .filter(field -> field.getUuid().equals(otherPersonAddress.getUuid())) + .findFirst() + .get() + .getAddressType()); + assertEquals( + I18nProperties.getString(Strings.messagePersonMergedAddressDescription), + leadPerson.getAddresses() + .stream() + .filter(field -> field.getUuid().equals(otherPersonAddress.getUuid())) + .findFirst() + .get() + .getAddressTypeDetails()); + } + private void updateFollowUpStatus(ContactDto contact, FollowUpStatus status) { contact = getContactFacade().getByUuid(contact.getUuid()); contact.setFollowUpStatus(status); From 0021854b006fe6e1b4cbd2583daf9ebabeee0e04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=A9=20Strysewske?= Date: Fri, 6 Jan 2023 11:00:30 +0100 Subject: [PATCH 073/166] #7305 - Fixes --- .../sormas/app/backend/common/AbstractAdoDao.java | 3 +-- .../app/backend/feature/FeatureConfigurationDao.java | 8 ++++++-- .../de/symeda/sormas/app/backend/person/PersonDao.java | 10 +++++----- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AbstractAdoDao.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AbstractAdoDao.java index a4122be3668..26e6388386a 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AbstractAdoDao.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AbstractAdoDao.java @@ -300,8 +300,7 @@ public List queryForObsolete() { where.and( where.isNotNull(AbstractDomainObject.CHANGE_DATE), where.eq(ADO.MODIFIED, false), - where.lt(AbstractDomainObject.CHANGE_DATE, maxChangeDate), - where.lt(AbstractDomainObject.LOCAL_CHANGE_DATE, maxChangeDate)); + where.lt(AbstractDomainObject.CHANGE_DATE, maxChangeDate)); return builder.query(); } catch (SQLException e) { throw new RuntimeException(e); diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/feature/FeatureConfigurationDao.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/feature/FeatureConfigurationDao.java index baa2f0e1a3e..3672ba1b792 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/feature/FeatureConfigurationDao.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/feature/FeatureConfigurationDao.java @@ -119,9 +119,13 @@ public Integer getIntegerPropertyValue(FeatureType featureType, FeatureTypePrope throw new RuntimeException(e); } - boolean result; if (propertyObjectMap != null && propertyObjectMap.containsKey(property)) { - return (Integer) propertyObjectMap.get(property); + try { + return (Integer) propertyObjectMap.get(property); + } catch (ClassCastException e) { + Double doubleValue = (Double) propertyObjectMap.get(property); + return doubleValue != null ? doubleValue.intValue() : null; + } } else { return null; } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/person/PersonDao.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/person/PersonDao.java index e63cec9f353..48adb6ec3d4 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/person/PersonDao.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/person/PersonDao.java @@ -15,16 +15,16 @@ package de.symeda.sormas.app.backend.person; -import android.util.Log; +import java.sql.SQLException; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; import com.j256.ormlite.dao.Dao; import com.j256.ormlite.stmt.QueryBuilder; import com.j256.ormlite.stmt.Where; -import java.sql.SQLException; -import java.util.Date; -import java.util.List; -import java.util.stream.Collectors; +import android.util.Log; import de.symeda.sormas.api.person.PersonNameDto; import de.symeda.sormas.api.person.PersonSimilarityCriteria; From eaef5e2cb5883f08812e0848b9eb55c2e5c3bbaf Mon Sep 17 00:00:00 2001 From: Carina Paul <47103965+carina29@users.noreply.github.com> Date: Fri, 6 Jan 2023 18:06:44 +0200 Subject: [PATCH 074/166] =?UTF-8?q?=20#11076=20-=20delete=20icon=20should?= =?UTF-8?q?=20appear=20if=20the=20case/event=20was=20shared=20with?= =?UTF-8?q?=E2=80=A6=20(#11281)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * #11076 - delete icon should appear if the case/event was shared with Reporting Tool --- .../api/share/ExternalShareInfoFacade.java | 2 + .../share/ExternalShareInfoFacadeEjb.java | 21 ++++++++ ...lSurveillanceToolGatewayFacadeEjbTest.java | 25 +++++++++ .../ExternalSurveillanceShareComponent.java | 51 ++++++++++++------- 4 files changed, 80 insertions(+), 19 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/share/ExternalShareInfoFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/share/ExternalShareInfoFacade.java index 19b4cc32115..402d776a2d4 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/share/ExternalShareInfoFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/share/ExternalShareInfoFacade.java @@ -25,4 +25,6 @@ public interface ExternalShareInfoFacade { List getIndexList(ExternalShareInfoCriteria criteria, Integer first, Integer max); boolean isSharedCase(String caseUuid); + + boolean isSharedEvent(String eventUuid); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/share/ExternalShareInfoFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/share/ExternalShareInfoFacadeEjb.java index 47a57822456..cd48472b6e4 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/share/ExternalShareInfoFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/share/ExternalShareInfoFacadeEjb.java @@ -39,6 +39,7 @@ import de.symeda.sormas.api.share.ExternalShareStatus; import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; +import de.symeda.sormas.backend.event.Event; import de.symeda.sormas.backend.user.UserFacadeEjb; import de.symeda.sormas.backend.user.UserService; import de.symeda.sormas.backend.util.DtoHelper; @@ -103,6 +104,26 @@ public boolean isSharedCase(String caseUuid) { return ExternalShareStatus.SHARED.equals(externalShareStatus); } + @Override + public boolean isSharedEvent(String eventUuid) { + final CriteriaBuilder cb = em.getCriteriaBuilder(); + final CriteriaQuery cq = cb.createQuery(ExternalShareStatus.class); + final Root shareInfo = cq.from(ExternalShareInfo.class); + Join eventJoin = shareInfo.join(ExternalShareInfo.EVENT, JoinType.LEFT); + + cq.select(shareInfo.get(ExternalShareInfo.STATUS)); + cq.where(cb.equal(eventJoin.get(Event.UUID), eventUuid)); + cq.orderBy(cb.desc(shareInfo.get(ExternalShareInfo.CREATION_DATE))); + + ExternalShareStatus externalShareStatus = null; + try { + externalShareStatus = em.createQuery(cq).setMaxResults(1).getSingleResult(); + } catch (NoResultException e) { + } + + return ExternalShareStatus.SHARED.equals(externalShareStatus); + } + private ExternalShareInfoDto convertToDto(ExternalShareInfo source, Pseudonymizer pseudonymizer) { ExternalShareInfoDto dto = toDto(source); diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/externalsurveillancetool/ExternalSurveillanceToolGatewayFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/externalsurveillancetool/ExternalSurveillanceToolGatewayFacadeEjbTest.java index 1d4a964113c..60573e27d36 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/externalsurveillancetool/ExternalSurveillanceToolGatewayFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/externalsurveillancetool/ExternalSurveillanceToolGatewayFacadeEjbTest.java @@ -430,6 +430,31 @@ public void testIsSharedCase() throws ExternalSurveillanceToolException { assertTrue(shared); } + @Test + public void testIsSharedEvent() throws ExternalSurveillanceToolException { + TestDataCreator.RDCF rdcf = creator.createRDCF(); + UserDto user = creator + .createUser(rdcf, creator.getUserRoleReference(DefaultUserRole.ADMIN), creator.getUserRoleReference(DefaultUserRole.NATIONAL_USER)); + PersonDto person = creator.createPerson(); + CaseDataDto caze = creator.createCase(user.toReference(), person.toReference(), rdcf, c -> c.setDontShareWithReportingTool(true)); + + EventDto event1 = creator.createEvent(user.toReference(), caze.getDisease()); + EventDto event2 = creator.createEvent(user.toReference(), caze.getDisease()); + + stubFor( + post(urlEqualTo("/export")).withRequestBody(containing(event1.getUuid())) + .withRequestBody(containing("eventUuids")) + .willReturn(aResponse().withStatus(HttpStatus.SC_OK))); + + getExternalSurveillanceToolGatewayFacade().sendEvents(Arrays.asList(event1.getUuid()), false); + + boolean shared = getExternalShareInfoFacade().isSharedEvent(event1.getUuid()); + assertTrue(shared); + + shared = getExternalShareInfoFacade().isSharedCase(event2.getUuid()); + assertFalse(shared); + } + @Test public void testArchiveAllArchivableCases_WithNotAllowedCaseToShareWithReportingTool(WireMockRuntimeInfo wireMockRuntime) { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalsurveillanceservice/ExternalSurveillanceShareComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalsurveillanceservice/ExternalSurveillanceShareComponent.java index ea2ffefa868..8750c74b9e9 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalsurveillanceservice/ExternalSurveillanceShareComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalsurveillanceservice/ExternalSurveillanceShareComponent.java @@ -24,7 +24,6 @@ import com.vaadin.ui.themes.ValoTheme; import de.symeda.sormas.api.FacadeProvider; -import de.symeda.sormas.api.caze.CaseDataDto; import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.i18n.Strings; @@ -58,11 +57,15 @@ private void initLayout( setSpacing(false); addStyleNames(CssStyles.SIDE_COMPONENT); - String caseUuid = null; if (shareInfoCriteria.getCaze() != null) { - caseUuid = shareInfoCriteria.getCaze().getUuid(); + String caseUuid = shareInfoCriteria.getCaze().getUuid(); + addComponent(createHeader(entityString, sendHandler, deleteHandler, editComponent, caseUuid, null)); + } + + if (shareInfoCriteria.getEvent() != null) { + String eventUuid = shareInfoCriteria.getEvent().getUuid(); + addComponent(createHeader(entityString, sendHandler, deleteHandler, editComponent, null, eventUuid)); } - addComponent(createHeader(entityString, sendHandler, deleteHandler, editComponent, caseUuid)); addComponent(createShareInfoList(shareInfoCriteria)); } @@ -71,7 +74,8 @@ private HorizontalLayout createHeader( Runnable sendHandler, Runnable deleteHandler, DirtyStateComponent editComponent, - String caseUuid) { + String caseUuid, + String eventUuid) { Label header = new Label(I18nProperties.getCaption(Captions.ExternalSurveillanceToolGateway_title)); header.addStyleName(CssStyles.H3); @@ -89,26 +93,35 @@ private HorizontalLayout createHeader( headerLayout.setExpandRatio(sendButton, 1); headerLayout.setComponentAlignment(sendButton, Alignment.MIDDLE_RIGHT); } - if (deleteHandler != null && isVisibleDeleteButton(caseUuid)) { - Button deleteButton = ButtonHelper.createIconButton("", VaadinIcons.TRASH, e -> deleteHandler.run(), ValoTheme.BUTTON_ICON_ONLY); - headerLayout.addComponent(deleteButton); - headerLayout.setComponentAlignment(deleteButton, Alignment.MIDDLE_RIGHT); - headerLayout.setWidth(100, Unit.PERCENTAGE); + + if (caseUuid != null) { + if (deleteHandler != null && isVisibleDeleteButtonForCase(caseUuid)) { + addDeleteButtonToLayout(deleteHandler, headerLayout); + } + } + + if (eventUuid != null) { + if (deleteHandler != null && isVisibleDeleteButtonForEvent(eventUuid)) { + addDeleteButtonToLayout(deleteHandler, headerLayout); + } } return headerLayout; } - private boolean isVisibleDeleteButton(String caseUuid) { - if (caseUuid != null) { - CaseDataDto caseDataDto = FacadeProvider.getCaseFacade().getCaseDataByUuid(caseUuid); - boolean isSharedCase = FacadeProvider.getExternalShareInfoFacade().isSharedCase(caseUuid); + private void addDeleteButtonToLayout(Runnable deleteHandler, HorizontalLayout headerLayout) { + Button deleteButton = ButtonHelper.createIconButton("", VaadinIcons.TRASH, e -> deleteHandler.run(), ValoTheme.BUTTON_ICON_ONLY); + headerLayout.addComponent(deleteButton); + headerLayout.setComponentAlignment(deleteButton, Alignment.MIDDLE_RIGHT); + headerLayout.setWidth(100, Unit.PERCENTAGE); + } - if (caseDataDto.isDontShareWithReportingTool() && !isSharedCase) { - return false; - } - } - return true; + private boolean isVisibleDeleteButtonForCase(String caseUuid) { + return FacadeProvider.getExternalShareInfoFacade().isSharedCase(caseUuid); + } + + private boolean isVisibleDeleteButtonForEvent(String eventUuid) { + return FacadeProvider.getExternalShareInfoFacade().isSharedEvent(eventUuid); } private ExternalShareInfoList createShareInfoList(ExternalShareInfoCriteria criteria) { From b37bbdd2c64dfb4041ba2ddc660b46e81915367c Mon Sep 17 00:00:00 2001 From: Razvan Date: Sat, 7 Jan 2023 12:43:08 +0200 Subject: [PATCH 075/166] #10673-UpdateRerunParameter : updated rerun param to 1 to decrease long regression run --- .../java/org/sormas/e2etests/runner/CucumberTestRunner.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/runner/CucumberTestRunner.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/runner/CucumberTestRunner.java index ca42a03a16a..499de598b1a 100755 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/runner/CucumberTestRunner.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/runner/CucumberTestRunner.java @@ -29,7 +29,7 @@ runLevel = CourgetteRunLevel.SCENARIO, showTestOutput = true, rerunFailedScenarios = true, - rerunAttempts = 3, + rerunAttempts = 1, cucumberOptions = @CucumberOptions( features = "src/test/resources/features", From 855418c5172dfd9f4c0b53218d809a12cfad87f7 Mon Sep 17 00:00:00 2001 From: Levente Gal <62599627+leventegal-she@users.noreply.github.com> Date: Mon, 9 Jan 2023 10:23:11 +0200 Subject: [PATCH 076/166] #10247 S2S Surveillance Reports should be shareable (along with possibly attached External Messages) (#11147) * #10247 S2S Surveillance Reports should be shareable (along with possibly attached External Messages) - WIP * #10247 S2S Surveillance Reports should be shareable (along with possibly attached External Messages) - WIP * #10247 S2S Surveillance Reports should be shareable (along with possibly attached External Messages) - WIP * #10247 S2S Surveillance Reports should be shareable (along with possibly attached External Messages) - WIP * #10247 S2S Surveillance Reports should be shareable (along with possibly attached External Messages) - sync * #10247 S2S Surveillance Reports should be shareable (along with possibly attached External Messages) - review fixes Co-authored-by: Levente Gal --- .../SurveillanceReportCriteria.java | 13 + .../SurveillanceReportDto.java | 34 ++- .../SurveillanceReportFacade.java | 12 +- .../sormas/api/feature/FeatureType.java | 2 + .../api/feature/FeatureTypeProperty.java | 3 +- .../de/symeda/sormas/api/i18n/Captions.java | 3 +- .../de/symeda/sormas/api/i18n/Strings.java | 1 + .../symeda/sormas/api/i18n/Validations.java | 1 + .../api/sormastosormas/SormasToSormasDto.java | 11 + .../SormasToSormasOptionsDto.java | 12 + .../SormasToSormasOriginInfoDto.java | 9 + .../SormasToSormasSurveillanceReportDto.java | 38 +++ .../SormasToSormasShareInfoCriteria.java | 20 +- .../outgoing/SormasToSormasShareInfoDto.java | 9 + .../src/main/resources/captions.properties | 3 +- .../src/main/resources/strings.properties | 1 + .../src/main/resources/validations.properties | 1 + .../sormas/backend/caze/CaseFacadeEjb.java | 4 +- .../sormas/backend/caze/CaseService.java | 2 +- .../SurveillanceReport.java | 68 ++++- .../SurveillanceReportFacadeEjb.java | 280 ++++++++++++------ .../SurveillanceReportService.java | 4 + .../ExternalMessageFacadeEjb.java | 3 +- .../AbstractSormasToSormasInterface.java | 31 +- .../SormasToSormasFacadeEjb.java | 11 + .../sormastosormas/ValidationHelper.java | 24 +- .../entities/ProcessedEntitiesPersister.java | 20 ++ .../entities/ReceivedEntitiesProcessor.java | 17 ++ .../entities/ShareDataBuilder.java | 15 + .../entities/ShareDataExistingEntities.java | 10 +- .../SormasToSormasEntitiesHelper.java | 9 + .../caze/SormasToSormasCaseFacadeEjb.java | 15 +- .../sample/SampleShareDataBuilder.java | 20 +- ...cessedSurveillanceReportDataPersister.java | 91 ++++++ .../ReceivedSurveillanceReportProcessor.java | 81 +++++ ...oSormasSurveillanceReportDtoValidator.java | 80 +++++ .../SurveillanceReportShareDataBuilder.java | 90 ++++++ .../origin/SormasToSormasOriginInfo.java | 11 + .../SormasToSormasOriginInfoFacadeEjb.java | 2 + .../share/ShareDataBuilderHelper.java | 20 ++ .../share/outgoing/ShareRequestInfo.java | 11 + .../outgoing/SormasToSormasShareInfo.java | 20 +- .../SormasToSormasShareInfoFacadeEjb.java | 1 + .../SormasToSormasShareInfoService.java | 14 + .../src/main/resources/sql/sormas_schema.sql | 18 ++ .../sormas/backend/AbstractBeanTest.java | 7 +- .../sormas/backend/TestDataCreator.java | 14 +- .../caze/SurveillanceReportFacadeEjbTest.java | 69 +++++ .../SormasToSormasCaseFacadeEjbTest.java | 248 ++++++++++++++++ .../InfraValidationSoundnessTest.java | 27 ++ .../resources/SurveillanceReportResource.java | 2 +- .../SurveillanceReportController.java | 4 +- .../SurveillanceReportForm.java | 4 +- .../SurveillanceReportList.java | 13 +- .../ExternalMessageController.java | 4 +- .../SormasToSormasOptionsForm.java | 22 +- 56 files changed, 1385 insertions(+), 174 deletions(-) create mode 100644 sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/entities/surveillancereport/SormasToSormasSurveillanceReportDto.java create mode 100644 sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/surveillancereport/ProcessedSurveillanceReportDataPersister.java create mode 100644 sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/surveillancereport/ReceivedSurveillanceReportProcessor.java create mode 100644 sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/surveillancereport/SormasToSormasSurveillanceReportDtoValidator.java create mode 100644 sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/surveillancereport/SurveillanceReportShareDataBuilder.java create mode 100644 sormas-backend/src/test/java/de/symeda/sormas/backend/caze/SurveillanceReportFacadeEjbTest.java diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/caze/surveillancereport/SurveillanceReportCriteria.java b/sormas-api/src/main/java/de/symeda/sormas/api/caze/surveillancereport/SurveillanceReportCriteria.java index 227d9730033..81ba224887f 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/caze/surveillancereport/SurveillanceReportCriteria.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/caze/surveillancereport/SurveillanceReportCriteria.java @@ -15,6 +15,8 @@ package de.symeda.sormas.api.caze.surveillancereport; +import java.util.List; + import de.symeda.sormas.api.caze.CaseReferenceDto; import de.symeda.sormas.api.utils.criteria.BaseCriteria; @@ -24,6 +26,8 @@ public class SurveillanceReportCriteria extends BaseCriteria { private CaseReferenceDto caze; + private List caseUuids; + public CaseReferenceDto getCaze() { return caze; } @@ -33,4 +37,13 @@ public SurveillanceReportCriteria caze(CaseReferenceDto caze) { return this; } + + public List getCaseUuids() { + return caseUuids; + } + + public SurveillanceReportCriteria caseUuids(List caseUuids) { + this.caseUuids = caseUuids; + return this; + } } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/caze/surveillancereport/SurveillanceReportDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/caze/surveillancereport/SurveillanceReportDto.java index e4b2fc02419..a40cb7b0775 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/caze/surveillancereport/SurveillanceReportDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/caze/surveillancereport/SurveillanceReportDto.java @@ -17,6 +17,7 @@ import java.util.Date; +import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import de.symeda.sormas.api.caze.CaseReferenceDto; @@ -26,15 +27,15 @@ import de.symeda.sormas.api.infrastructure.facility.FacilityReferenceDto; import de.symeda.sormas.api.infrastructure.facility.FacilityType; import de.symeda.sormas.api.infrastructure.region.RegionReferenceDto; +import de.symeda.sormas.api.sormastosormas.SormasToSormasShareableDto; import de.symeda.sormas.api.user.UserReferenceDto; import de.symeda.sormas.api.utils.DataHelper; import de.symeda.sormas.api.utils.DependingOnFeatureType; import de.symeda.sormas.api.utils.FieldConstraints; import de.symeda.sormas.api.utils.SensitiveData; -import de.symeda.sormas.api.utils.pseudonymization.PseudonymizableDto; @DependingOnFeatureType(featureType = FeatureType.CASE_SURVEILANCE) -public class SurveillanceReportDto extends PseudonymizableDto { +public class SurveillanceReportDto extends SormasToSormasShareableDto { private static final long serialVersionUID = -8880285376883927386L; @@ -42,7 +43,7 @@ public class SurveillanceReportDto extends PseudonymizableDto { public static final String REPORTING_TYPE = "reportingType"; public static final String EXTERNAL_ID = "externalId"; - public static final String CREATING_USER = "creatingUser"; + public static final String REPORTING_USER = "reportingUser"; public static final String REPORT_DATE = "reportDate"; public static final String DATE_OF_DIAGNOSIS = "dateOfDiagnosis"; public static final String FACILITY_REGION = "facilityRegion"; @@ -51,23 +52,24 @@ public class SurveillanceReportDto extends PseudonymizableDto { public static final String FACILITY = "facility"; public static final String FACILITY_DETAILS = "facilityDetails"; public static final String NOTIFICATION_DETAILS = "notificationDetails"; + private UserReferenceDto reportingUser; - public static SurveillanceReportDto build(CaseReferenceDto caze, UserReferenceDto creatingUser) { + @NotNull + private ReportingType reportingType; + + private String externalId; + + public static SurveillanceReportDto build(CaseReferenceDto caze, UserReferenceDto reportingUser) { SurveillanceReportDto surveillanceReport = new SurveillanceReportDto(); surveillanceReport.setUuid(DataHelper.createUuid()); surveillanceReport.setCaze(caze); - surveillanceReport.setCreatingUser(creatingUser); + surveillanceReport.setReportingUser(reportingUser); return surveillanceReport; } - private ReportingType reportingType; - - private String externalId; - - private UserReferenceDto creatingUser; - + @NotNull private Date reportDate; private Date dateOfDiagnosis; @@ -106,12 +108,14 @@ public void setExternalId(String externalId) { this.externalId = externalId; } - public UserReferenceDto getCreatingUser() { - return creatingUser; + @Override + public UserReferenceDto getReportingUser() { + return reportingUser; } - public void setCreatingUser(UserReferenceDto creatingUser) { - this.creatingUser = creatingUser; + @Override + public void setReportingUser(UserReferenceDto reportingUser) { + this.reportingUser = reportingUser; } public Date getReportDate() { diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/caze/surveillancereport/SurveillanceReportFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/caze/surveillancereport/SurveillanceReportFacade.java index 4c8b7a593f5..0cc9c3790df 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/caze/surveillancereport/SurveillanceReportFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/caze/surveillancereport/SurveillanceReportFacade.java @@ -18,16 +18,14 @@ import java.util.List; import javax.ejb.Remote; -import javax.validation.Valid; -@Remote -public interface SurveillanceReportFacade { - - SurveillanceReportDto saveSurveillanceReport(@Valid SurveillanceReportDto dto); +import de.symeda.sormas.api.BaseFacade; - void deleteSurveillanceReport(String surveillanceReportUuid); +@Remote +public interface SurveillanceReportFacade + extends BaseFacade { - List getIndexList(SurveillanceReportCriteria criteria, Integer first, Integer max); + void delete(String surveillanceReportUuid); List getByCaseUuids(List caseUuids); } 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 b08287e6a9c..90c027b0f65 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 @@ -157,6 +157,8 @@ public enum FeatureType { FeatureTypeProperty.SHARE_SAMPLES, Boolean.TRUE, FeatureTypeProperty.SHARE_IMMUNIZATIONS, + Boolean.TRUE, + FeatureTypeProperty.SHARE_REPORTS, Boolean.TRUE)), SORMAS_TO_SORMAS_SHARE_CONTACTS(true, true, 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 896845fd63e..e34c8301313 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 @@ -26,7 +26,8 @@ public enum FeatureTypeProperty { S2S_SHARING(Boolean.class), SHARE_ASSOCIATED_CONTACTS(Boolean.class), SHARE_SAMPLES(Boolean.class), - SHARE_IMMUNIZATIONS(Boolean.class); + SHARE_IMMUNIZATIONS(Boolean.class), + SHARE_REPORTS(Boolean.class); private final Class returnType; diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java index fa4d3352e25..1834de1af10 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java @@ -2024,6 +2024,7 @@ public interface Captions { String SormasToSormasOptions_withEventParticipants = "SormasToSormasOptions.withEventParticipants"; String SormasToSormasOptions_withImmunizations = "SormasToSormasOptions.withImmunizations"; String SormasToSormasOptions_withSamples = "SormasToSormasOptions.withSamples"; + String SormasToSormasOptions_withSurveillanceReports = "SormasToSormasOptions.withSurveillanceReports"; String sormasToSormasOriginInfo = "sormasToSormasOriginInfo"; String sormasToSormasOwnedBy = "sormasToSormasOwnedBy"; String SormasToSormasPerson_address = "SormasToSormasPerson.address"; @@ -2087,7 +2088,6 @@ public interface Captions { String subcontinentAllSubcontinents = "subcontinentAllSubcontinents"; String subcontinentArchivedSubcontinents = "subcontinentArchivedSubcontinents"; String SurveillanceReport = "SurveillanceReport"; - String SurveillanceReport_creatingUser = "SurveillanceReport.creatingUser"; String SurveillanceReport_dateOfDiagnosis = "SurveillanceReport.dateOfDiagnosis"; String SurveillanceReport_externalId = "SurveillanceReport.externalId"; String SurveillanceReport_facility = "SurveillanceReport.facility"; @@ -2099,6 +2099,7 @@ public interface Captions { String SurveillanceReport_notificationDetails = "SurveillanceReport.notificationDetails"; String SurveillanceReport_reportDate = "SurveillanceReport.reportDate"; String SurveillanceReport_reportingType = "SurveillanceReport.reportingType"; + String SurveillanceReport_reportingUser = "SurveillanceReport.reportingUser"; String SurveillanceReport_uuid = "SurveillanceReport.uuid"; String surveillanceReportNewReport = "surveillanceReportNewReport"; String surveillanceReportNoReportsForCase = "surveillanceReportNoReportsForCase"; 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 6669f54f3ee..ed621358762 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 @@ -344,6 +344,7 @@ public interface Strings { String errorSormasToSormasShare = "errorSormasToSormasShare"; String errorSormasToSormasShareContactWithoutCase = "errorSormasToSormasShareContactWithoutCase"; String errorSormasToSormasShareContactWithUnsharedSourceCase = "errorSormasToSormasShareContactWithUnsharedSourceCase"; + String errorSurveillanceReportNotEditable = "errorSurveillanceReportNotEditable"; String errorTemplateFileCorrupt = "errorTemplateFileCorrupt"; String errorViewNotFound = "errorViewNotFound"; String errorWasReported = "errorWasReported"; 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 4d428fe71c2..8d91a5f57f7 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 @@ -213,6 +213,7 @@ public interface Validations { String sormasToSormasSenderNameMissing = "sormasToSormasSenderNameMissing"; String sormasToSormasShareInfoMissing = "sormasToSormasShareInfoMissing"; String sormasToSormasSubcontinent = "sormasToSormasSubcontinent"; + String sormasToSormasSurveillanceReportExists = "sormasToSormasSurveillanceReportExists"; String specifyCaption = "specifyCaption"; String specifyEpiWeek = "specifyEpiWeek"; String specifyFirstName = "specifyFirstName"; diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/SormasToSormasDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/SormasToSormasDto.java index f98a429b70f..f0935eb94b1 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/SormasToSormasDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/SormasToSormasDto.java @@ -26,6 +26,7 @@ import de.symeda.sormas.api.sormastosormas.entities.event.SormasToSormasEventParticipantDto; import de.symeda.sormas.api.sormastosormas.entities.immunization.SormasToSormasImmunizationDto; import de.symeda.sormas.api.sormastosormas.entities.sample.SormasToSormasSampleDto; +import de.symeda.sormas.api.sormastosormas.entities.surveillancereport.SormasToSormasSurveillanceReportDto; public class SormasToSormasDto implements Serializable { @@ -46,6 +47,8 @@ public class SormasToSormasDto implements Serializable { private List eventParticipants; @Valid private List immunizations; + @Valid + private List surveillanceReports; public SormasToSormasOriginInfoDto getOriginInfo() { return originInfo; @@ -102,4 +105,12 @@ public List getImmunizations() { public void setImmunizations(List immunizations) { this.immunizations = immunizations; } + + public List getSurveillanceReports() { + return surveillanceReports; + } + + public void setSurveillanceReports(List surveillanceReports) { + this.surveillanceReports = surveillanceReports; + } } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/SormasToSormasOptionsDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/SormasToSormasOptionsDto.java index 3cd67a86af5..d57a7484c9a 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/SormasToSormasOptionsDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/SormasToSormasOptionsDto.java @@ -43,6 +43,8 @@ public class SormasToSormasOptionsDto implements Serializable { public static final String WITH_EVENT_PARTICIPANTS = "withEventParticipants"; public static final String WITH_IMMUNIZATIONS = "withImmunizations"; + public static final String WITH_SURVEILLANCE_REPORTS = "withSurveillanceReports"; + // Fixme this should be renamed but it has strange side effects with the UI private SormasServerDescriptor organization; @@ -62,6 +64,8 @@ public class SormasToSormasOptionsDto implements Serializable { private boolean withImmunizations; + private boolean withSurveillanceReports; + // FIXME(#6101): This should be renamed as it is the target of the operation public SormasServerDescriptor getOrganization() { return organization; @@ -126,4 +130,12 @@ public boolean isWithImmunizations() { public void setWithImmunizations(boolean withImmunizations) { this.withImmunizations = withImmunizations; } + + public boolean isWithSurveillanceReports() { + return withSurveillanceReports; + } + + public void setWithSurveillanceReports(boolean withSurveillanceReports) { + this.withSurveillanceReports = withSurveillanceReports; + } } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/SormasToSormasOriginInfoDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/SormasToSormasOriginInfoDto.java index a9704654c2f..acfce3e0405 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/SormasToSormasOriginInfoDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/SormasToSormasOriginInfoDto.java @@ -39,6 +39,7 @@ public class SormasToSormasOriginInfoDto extends EntityDto { private boolean withSamples; private boolean withEventParticipants; private boolean withImmunizations; + private boolean withSurveillanceReports; private boolean pseudonymizedData; @NotEmpty(message = Validations.requiredField) @@ -120,6 +121,14 @@ public void setWithImmunizations(boolean withImmunizations) { this.withImmunizations = withImmunizations; } + public boolean isWithSurveillanceReports() { + return withSurveillanceReports; + } + + public void setWithSurveillanceReports(boolean withSurveillanceReports) { + this.withSurveillanceReports = withSurveillanceReports; + } + public String getComment() { return comment; } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/entities/surveillancereport/SormasToSormasSurveillanceReportDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/entities/surveillancereport/SormasToSormasSurveillanceReportDto.java new file mode 100644 index 00000000000..94ee959e59a --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/entities/surveillancereport/SormasToSormasSurveillanceReportDto.java @@ -0,0 +1,38 @@ +/* + * SORMAS® - Surveillance Outbreak Response Management & Analysis System + * Copyright © 2016-2022 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.symeda.sormas.api.sormastosormas.entities.surveillancereport; + +import de.symeda.sormas.api.caze.surveillancereport.SurveillanceReportDto; +import de.symeda.sormas.api.sormastosormas.entities.SormasToSormasEntityDto; +import de.symeda.sormas.api.sormastosormas.entities.externalmessage.SormasToSormasExternalMessageDto; + +public class SormasToSormasSurveillanceReportDto extends SormasToSormasEntityDto { + + private final SormasToSormasExternalMessageDto externalMessage; + + public SormasToSormasSurveillanceReportDto() { + externalMessage = null; + } + + public SormasToSormasSurveillanceReportDto(SurveillanceReportDto entity, SormasToSormasExternalMessageDto externalMessage) { + super(entity); + this.externalMessage = externalMessage; + } + + public SormasToSormasExternalMessageDto getExternalMessage() { + return externalMessage; + } +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/share/outgoing/SormasToSormasShareInfoCriteria.java b/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/share/outgoing/SormasToSormasShareInfoCriteria.java index b0be30f5c85..36dbbf53bbc 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/share/outgoing/SormasToSormasShareInfoCriteria.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/share/outgoing/SormasToSormasShareInfoCriteria.java @@ -1,24 +1,22 @@ /* * SORMAS® - Surveillance Outbreak Response Management & Analysis System * Copyright © 2016-2022 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) - * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * 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 . + * along with this program. If not, see . */ package de.symeda.sormas.api.sormastosormas.share.outgoing; import de.symeda.sormas.api.caze.CaseReferenceDto; +import de.symeda.sormas.api.caze.surveillancereport.SurveillanceReportReferenceDto; import de.symeda.sormas.api.contact.ContactReferenceDto; import de.symeda.sormas.api.event.EventParticipantReferenceDto; import de.symeda.sormas.api.event.EventReferenceDto; @@ -42,6 +40,8 @@ public class SormasToSormasShareInfoCriteria extends BaseCriteria { private ImmunizationReferenceDto immunization; + private SurveillanceReportReferenceDto surveillanceReport; + public CaseReferenceDto getCaze() { return caze; } @@ -101,4 +101,14 @@ public SormasToSormasShareInfoCriteria immunization(ImmunizationReferenceDto imm return this; } + + public SurveillanceReportReferenceDto getSurveillanceReport() { + return surveillanceReport; + } + + public SormasToSormasShareInfoCriteria surveillanceReport(SurveillanceReportReferenceDto surveillanceReport) { + this.surveillanceReport = surveillanceReport; + + return this; + } } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/share/outgoing/SormasToSormasShareInfoDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/share/outgoing/SormasToSormasShareInfoDto.java index 0ffb69f44e8..452a7d3664f 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/share/outgoing/SormasToSormasShareInfoDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/sormastosormas/share/outgoing/SormasToSormasShareInfoDto.java @@ -38,6 +38,7 @@ public class SormasToSormasShareInfoDto extends EntityDto { private boolean withSamples; private boolean withEvenParticipants; private boolean withImmunizations; + private boolean withSurveillanceReports; private boolean pseudonymizedPersonalData; private boolean pseudonymizedSensitiveData; @Size(max = FieldConstraints.CHARACTER_LIMIT_BIG, message = Validations.textTooLong) @@ -109,6 +110,14 @@ public void setWithImmunizations(boolean withImmunizations) { this.withImmunizations = withImmunizations; } + public boolean isWithSurveillanceReports() { + return withSurveillanceReports; + } + + public void setWithSurveillanceReports(boolean withSurveillanceReports) { + this.withSurveillanceReports = withSurveillanceReports; + } + public boolean isPseudonymizedPersonalData() { return pseudonymizedPersonalData; } diff --git a/sormas-api/src/main/resources/captions.properties b/sormas-api/src/main/resources/captions.properties index cfb2d4e87c2..ff1bf11a080 100644 --- a/sormas-api/src/main/resources/captions.properties +++ b/sormas-api/src/main/resources/captions.properties @@ -2599,6 +2599,7 @@ SormasToSormasOptions.withAssociatedContacts=Share associated contacts SormasToSormasOptions.withSamples=Share samples SormasToSormasOptions.withEventParticipants=Share event participants SormasToSormasOptions.withImmunizations=Share immunizations +SormasToSormasOptions.withSurveillanceReports=Share reports SormasToSormasOptions.handOverOwnership=Hand over the ownership SormasToSormasOptions.pseudonymizeData=Exclude personal data SormasToSormasOptions.comment=Comment @@ -2639,7 +2640,7 @@ SurveillanceReport=Report SurveillanceReport.uuid=Report-Id SurveillanceReport.reportingType=Type of reporting SurveillanceReport.externalId=External Id -SurveillanceReport.creatingUser=Creating user +SurveillanceReport.reportingUser=Creating user SurveillanceReport.reportDate=Date of report SurveillanceReport.dateOfDiagnosis=Date of diagnosis SurveillanceReport.facilityRegion=Reporter facility region diff --git a/sormas-api/src/main/resources/strings.properties b/sormas-api/src/main/resources/strings.properties index 7aaa97b1a0f..8f1eb194f5d 100644 --- a/sormas-api/src/main/resources/strings.properties +++ b/sormas-api/src/main/resources/strings.properties @@ -396,6 +396,7 @@ errorForbidden = Access to the specified resource has been forbidden. Please con errorNoRightsForChangingField = You have no rights for changing %s errorNoRightsForChangingMultipleFields = You have no rights for changing %s and related fields errorDeleteUserRoleUsedAlone = Cannot delete user role, because the following users would remain without a user role:

%s

Please give them a different role and re-try to delete this one. +errorSurveillanceReportNotEditable = This report is not editable any more # headings headingAccessDenied = Access denied diff --git a/sormas-api/src/main/resources/validations.properties b/sormas-api/src/main/resources/validations.properties index 0ee51dcd8dc..45f94adefec 100644 --- a/sormas-api/src/main/resources/validations.properties +++ b/sormas-api/src/main/resources/validations.properties @@ -191,6 +191,7 @@ sormasToSormasSenderNameMissing = Sender name is missing sormasToSormasCommentMissing = Comment is missing sormasToSormasSampleExists = This sample already exists sormasToSormasImmunizationExists = This immunization already exists +sormasToSormasSurveillanceReportExists = This report already exists sormasToSormasReturnEntityNotExists = Object does not exist sormasToSormasSaveException = %s could not be saved: %s sormasToSormasContinent = Unmatched continent: %s 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 0d94a48df30..32d3dafeab1 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 @@ -3747,9 +3747,9 @@ private void mergeCase(CaseDataDto leadCaseData, CaseDataDto otherCaseData, bool // 9 Reports List surveillanceReports = surveillanceReportService.getByCaseUuids(Collections.singletonList(otherCase.getUuid())); surveillanceReports.forEach(surveillanceReport -> { - SurveillanceReportDto surveillanceReportDto = SurveillanceReportFacadeEjb.toDto(surveillanceReport); + SurveillanceReportDto surveillanceReportDto = surveillanceReportFacade.toDto(surveillanceReport); surveillanceReportDto.setCaze(leadCase.toReference()); - surveillanceReportFacade.saveSurveillanceReport(surveillanceReportDto); + surveillanceReportFacade.save(surveillanceReportDto); }); // 10 Activity as case 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 97609346384..ddea2cfb75d 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 @@ -1022,7 +1022,7 @@ public void deletePermanent(Case caze) { // Delete surveillance reports related to this case surveillanceReportService.getByCaseUuids(Collections.singletonList(caze.getUuid())) - .forEach(s -> surveillanceReportFacade.deleteSurveillanceReport(s.getUuid())); + .forEach(s -> surveillanceReportFacade.delete(s.getUuid())); // Delete documents related to this case documentService.getRelatedToEntity(DocumentRelatedEntityType.CASE, caze.getUuid()).forEach(d -> documentService.markAsDeleted(d)); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReport.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReport.java index 490097016ac..dca7621ed27 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReport.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReport.java @@ -15,38 +15,47 @@ package de.symeda.sormas.backend.caze.surveillancereport; +import java.util.ArrayList; import java.util.Date; +import java.util.List; +import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; import javax.persistence.FetchType; import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; import javax.persistence.Temporal; import javax.persistence.TemporalType; import de.symeda.auditlog.api.Audited; +import de.symeda.auditlog.api.AuditedIgnore; import de.symeda.sormas.api.caze.surveillancereport.ReportingType; -import de.symeda.sormas.api.caze.surveillancereport.SurveillanceReportReferenceDto; import de.symeda.sormas.api.infrastructure.facility.FacilityType; import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.common.AbstractDomainObject; +import de.symeda.sormas.backend.externalmessage.ExternalMessage; import de.symeda.sormas.backend.infrastructure.district.District; import de.symeda.sormas.backend.infrastructure.facility.Facility; import de.symeda.sormas.backend.infrastructure.region.Region; +import de.symeda.sormas.backend.sormastosormas.entities.SormasToSormasShareable; +import de.symeda.sormas.backend.sormastosormas.origin.SormasToSormasOriginInfo; +import de.symeda.sormas.backend.sormastosormas.share.outgoing.SormasToSormasShareInfo; import de.symeda.sormas.backend.user.User; @Entity(name = "surveillancereports") @Audited -public class SurveillanceReport extends AbstractDomainObject { +public class SurveillanceReport extends AbstractDomainObject implements SormasToSormasShareable { private static final long serialVersionUID = -2599492274783441938L; public static final String TABLE_NAME = "surveillancereports"; public static final String REPORTING_TYPE = "reportingType"; - public static final String CREATING_USER = "creatingUser"; + public static final String REPORTING_USER = "reportingUser"; public static final String REPORT_DATE = "reportDate"; public static final String DATE_OF_DIAGNOSIS = "dateOfDiagnosis"; public static final String FACILITY_REGION = "facilityRegion"; @@ -56,12 +65,14 @@ public class SurveillanceReport extends AbstractDomainObject { public static final String FACILITY_DETAILS = "facilityDetails"; public static final String NOTIFICATION_DETAILS = "notificationDetails"; public static final String CAZE = "caze"; + public static final String SORMAS_TO_SORMAS_ORIGIN_INFO = "sormasToSormasOriginInfo"; + public static final String SORMAS_TO_SORMAS_SHARES = "sormasToSormasShares"; private ReportingType reportingType; private String externalId; - private User creatingUser; + private User reportingUser; private Date reportDate; @@ -81,6 +92,11 @@ public class SurveillanceReport extends AbstractDomainObject { private Case caze; + private ExternalMessage externalMessage; + private SormasToSormasOriginInfo sormasToSormasOriginInfo; + + private List sormasToSormasShares = new ArrayList<>(0); + @Enumerated(EnumType.STRING) @Column(nullable = false) public ReportingType getReportingType() { @@ -99,13 +115,14 @@ public void setExternalId(String externalId) { this.externalId = externalId; } + @Override @ManyToOne(fetch = FetchType.LAZY) - public User getCreatingUser() { - return creatingUser; + public User getReportingUser() { + return reportingUser; } - public void setCreatingUser(User creatingUser) { - this.creatingUser = creatingUser; + public void setReportingUser(User reportingUser) { + this.reportingUser = reportingUser; } @Temporal(TemporalType.TIMESTAMP) @@ -190,7 +207,38 @@ public void setCaze(Case caze) { this.caze = caze; } - public SurveillanceReportReferenceDto toReference() { - return new SurveillanceReportReferenceDto(getUuid()); + @OneToOne(mappedBy = ExternalMessage.SURVEILLANCE_REPORT) + public ExternalMessage getExternalMessage() { + return externalMessage; + } + + public void setExternalMessage(ExternalMessage externalMessage) { + this.externalMessage = externalMessage; + } + + @Override + @ManyToOne(cascade = { + CascadeType.PERSIST, + CascadeType.MERGE, + CascadeType.DETACH, + CascadeType.REFRESH }) + @AuditedIgnore + public SormasToSormasOriginInfo getSormasToSormasOriginInfo() { + return sormasToSormasOriginInfo; + } + + @Override + public void setSormasToSormasOriginInfo(SormasToSormasOriginInfo sormasToSormasOriginInfo) { + this.sormasToSormasOriginInfo = sormasToSormasOriginInfo; + } + + @OneToMany(mappedBy = SormasToSormasShareInfo.SURVEILLANCE_REPORT, fetch = FetchType.LAZY) + @AuditedIgnore + public List getSormasToSormasShares() { + return sormasToSormasShares; + } + + public void setSormasToSormasShares(List sormasToSormasShares) { + this.sormasToSormasShares = sormasToSormasShares; } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportFacadeEjb.java index 8f670696166..7995884da60 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportFacadeEjb.java @@ -16,12 +16,14 @@ package de.symeda.sormas.backend.caze.surveillancereport; import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; +import java.util.concurrent.TimeUnit; +import javax.annotation.Resource; import javax.ejb.EJB; import javax.ejb.LocalBean; import javax.ejb.Stateless; +import javax.enterprise.concurrent.ManagedScheduledExecutorService; +import javax.inject.Inject; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.criteria.CriteriaBuilder; @@ -31,23 +33,36 @@ import javax.validation.Valid; import javax.validation.constraints.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import de.symeda.sormas.api.caze.surveillancereport.SurveillanceReportCriteria; import de.symeda.sormas.api.caze.surveillancereport.SurveillanceReportDto; import de.symeda.sormas.api.caze.surveillancereport.SurveillanceReportFacade; import de.symeda.sormas.api.caze.surveillancereport.SurveillanceReportReferenceDto; import de.symeda.sormas.api.externalmessage.ExternalMessageDto; -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.sormastosormas.ShareTreeCriteria; import de.symeda.sormas.api.user.UserRight; +import de.symeda.sormas.api.utils.AccessDeniedException; +import de.symeda.sormas.api.utils.SortProperty; +import de.symeda.sormas.api.utils.ValidationRuntimeException; import de.symeda.sormas.backend.caze.CaseFacadeEjb; import de.symeda.sormas.backend.caze.CaseService; -import de.symeda.sormas.backend.externalmessage.ExternalMessageFacadeEjb; +import de.symeda.sormas.backend.common.AbstractBaseEjb; +import de.symeda.sormas.backend.externalmessage.ExternalMessageFacadeEjb.ExternalMessageFacadeEjbLocal; import de.symeda.sormas.backend.infrastructure.district.DistrictFacadeEjb; import de.symeda.sormas.backend.infrastructure.district.DistrictService; import de.symeda.sormas.backend.infrastructure.facility.FacilityFacadeEjb; import de.symeda.sormas.backend.infrastructure.facility.FacilityService; import de.symeda.sormas.backend.infrastructure.region.RegionFacadeEjb; import de.symeda.sormas.backend.infrastructure.region.RegionService; +import de.symeda.sormas.backend.sormastosormas.SormasToSormasFacadeEjb.SormasToSormasFacadeEjbLocal; +import de.symeda.sormas.backend.sormastosormas.entities.caze.SormasToSormasCaseFacadeEjb.SormasToSormasCaseFacadeEjbLocal; +import de.symeda.sormas.backend.sormastosormas.origin.SormasToSormasOriginInfoFacadeEjb; +import de.symeda.sormas.backend.sormastosormas.origin.SormasToSormasOriginInfoService; +import de.symeda.sormas.backend.sormastosormas.share.outgoing.ShareInfoHelper; import de.symeda.sormas.backend.user.User; import de.symeda.sormas.backend.user.UserService; import de.symeda.sormas.backend.util.DtoHelper; @@ -58,15 +73,16 @@ @Stateless(name = "SurveillanceReportFacade") @RightsAllowed(UserRight._CASE_VIEW) -public class SurveillanceReportFacadeEjb implements SurveillanceReportFacade { +public class SurveillanceReportFacadeEjb + extends + AbstractBaseEjb + implements SurveillanceReportFacade { + + private final Logger logger = LoggerFactory.getLogger(SurveillanceReportFacadeEjb.class); @PersistenceContext(unitName = ModelConstants.PERSISTENCE_UNIT_NAME) private EntityManager em; @EJB - private SurveillanceReportService service; - @EJB - private UserService userService; - @EJB private RegionService regionService; @EJB private DistrictService districtService; @@ -75,68 +91,60 @@ public class SurveillanceReportFacadeEjb implements SurveillanceReportFacade { @EJB private CaseService caseService; @EJB - private ExternalMessageFacadeEjb.ExternalMessageFacadeEjbLocal externalMessageFacade; - - public static SurveillanceReportDto toDto(SurveillanceReport source) { - if (source == null) { - return null; - } - - SurveillanceReportDto target = new SurveillanceReportDto(); - DtoHelper.fillDto(target, source); + private ExternalMessageFacadeEjbLocal externalMessageFacade; + @EJB + private SormasToSormasOriginInfoService originInfoService; + @EJB + private SormasToSormasFacadeEjbLocal sormasToSormasFacade; + @Resource + private ManagedScheduledExecutorService executorService; + @EJB + private SormasToSormasCaseFacadeEjbLocal sormasToSormasCaseFacade; - target.setReportingType(source.getReportingType()); - target.setExternalId(source.getExternalId()); - target.setCreatingUser(source.getCreatingUser() == null ? null : source.getCreatingUser().toReference()); - target.setReportDate(source.getReportDate()); - target.setDateOfDiagnosis(source.getDateOfDiagnosis()); - target.setFacilityRegion(RegionFacadeEjb.toReferenceDto(source.getFacilityRegion())); - target.setFacilityDistrict(DistrictFacadeEjb.toReferenceDto(source.getFacilityDistrict())); - target.setFacilityType(source.getFacilityType()); - target.setFacility(FacilityFacadeEjb.toReferenceDto(source.getFacility())); - target.setFacilityDetails(source.getFacilityDetails()); - target.setNotificationDetails(source.getNotificationDetails()); - target.setCaze(CaseFacadeEjb.toReferenceDto(source.getCaze())); + public SurveillanceReportFacadeEjb() { + super(); + } - return target; + @Inject + public SurveillanceReportFacadeEjb(SurveillanceReportService service, UserService userService) { + super(SurveillanceReport.class, SurveillanceReportDto.class, service, userService); + } + public static SurveillanceReportReferenceDto toReferenceDto(SurveillanceReport entity) { + if (entity == null) { + return null; + } + return new SurveillanceReportReferenceDto(entity.getUuid()); } @Override @RightsAllowed(UserRight._CASE_EDIT) - public SurveillanceReportDto saveSurveillanceReport(@Valid SurveillanceReportDto dto) { - return saveSurveillanceReport(dto, true); + public SurveillanceReportDto save(@Valid @NotNull SurveillanceReportDto dto) { + return saveSurveillanceReport(dto, true, true); } - private SurveillanceReportDto saveSurveillanceReport(SurveillanceReportDto dto, boolean checkChangeDate) { - SurveillanceReport existingReport = service.getByUuid(dto.getUuid()); - SurveillanceReportDto existingReportDto = toDto(existingReport); - - restorePseudonymizedDto(dto, existingReport, existingReportDto); - - SurveillanceReport report = fromDto(dto, checkChangeDate); - - service.ensurePersisted(report); + @Override + public long count(SurveillanceReportCriteria criteria) { + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(Long.class); - return toDto(report); - } + Root root = cq.from(SurveillanceReport.class); - @Override - @RightsAllowed({ - UserRight._CASE_EDIT, - UserRight._SYSTEM }) - public void deleteSurveillanceReport(String surveillanceReportUuid) { - ExternalMessageDto associatedMessage = - externalMessageFacade.getForSurveillanceReport(new SurveillanceReportReferenceDto(surveillanceReportUuid)); - if (associatedMessage != null) { - associatedMessage.setSurveillanceReport(null); - externalMessageFacade.save(associatedMessage); + Predicate filter = service.buildCriteriaFilter(criteria, cb, root); + if (filter != null) { + cq.where(filter); } - service.deletePermanent(service.getByUuid(surveillanceReportUuid)); + + cq.select(cb.countDistinct(root)); + return em.createQuery(cq).getSingleResult(); } @Override - public List getIndexList(SurveillanceReportCriteria criteria, Integer first, Integer max) { + public List getIndexList( + SurveillanceReportCriteria criteria, + Integer first, + Integer max, + List sortProperties) { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cq = cb.createQuery(SurveillanceReport.class); Root root = cq.from(SurveillanceReport.class); @@ -148,65 +156,169 @@ public List getIndexList(SurveillanceReportCriteria crite cq.orderBy(cb.desc(root.get(SurveillanceReport.CREATION_DATE))); - List resultList = QueryHelper.getResultList(em, cq, first, max); - List reports = resultList.stream().map(SurveillanceReportFacadeEjb::toDto).collect(Collectors.toList()); + return toPseudonymizedDtos(QueryHelper.getResultList(em, cq, first, max)); + } - List inJurisdictionIds = service.getInJurisdictionIds(resultList); - User currentUser = userService.getCurrentUser(); - Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService::hasRight, I18nProperties.getCaption(Captions.inaccessibleValue)); - pseudonymizer.pseudonymizeDtoCollection(SurveillanceReportDto.class, reports, reportDto -> { - Optional report = resultList.stream().filter(r -> r.getUuid().equals(r.getUuid())).findFirst(); - return report.isPresent() ? inJurisdictionIds.contains(report.get().getId()) : false; - }, (reportDto, inJurisdiction) -> { - Optional report = resultList.stream().filter(r -> r.getUuid().equals(r.getUuid())).findFirst(); - report.ifPresent( - surveillanceReport -> pseudonymizer.pseudonymizeUser(surveillanceReport.getCreatingUser(), currentUser, reportDto::setCreatingUser)); - }); + @Override + public void validate(@Valid SurveillanceReportDto dto) throws ValidationRuntimeException { - return reports; } @Override - public List getByCaseUuids(List caseUuids) { - return service.getByCaseUuids(caseUuids).stream().map(SurveillanceReportFacadeEjb::toDto).collect(Collectors.toList()); + protected SurveillanceReport fillOrBuildEntity(SurveillanceReportDto source, SurveillanceReport target, boolean checkChangeDate) { + target = DtoHelper.fillOrBuildEntity(source, service.getByUuid(source.getUuid()), SurveillanceReport::new, checkChangeDate); + + target.setReportingType(source.getReportingType()); + target.setExternalId(source.getExternalId()); + target.setReportingUser(userService.getByReferenceDto(source.getReportingUser())); + target.setReportDate(source.getReportDate()); + target.setDateOfDiagnosis(source.getDateOfDiagnosis()); + target.setFacilityRegion(regionService.getByReferenceDto(source.getFacilityRegion())); + target.setFacilityDistrict(districtService.getByReferenceDto(source.getFacilityDistrict())); + target.setFacilityType(source.getFacilityType()); + target.setFacility(facilityService.getByReferenceDto(source.getFacility())); + target.setFacilityDetails(source.getFacilityDetails()); + target.setNotificationDetails(source.getNotificationDetails()); + target.setCaze(caseService.getByReferenceDto(source.getCaze())); + + if (source.getSormasToSormasOriginInfo() != null) { + target.setSormasToSormasOriginInfo(originInfoService.getByUuid(source.getSormasToSormasOriginInfo().getUuid())); + } + + return target; } - private void restorePseudonymizedDto(SurveillanceReportDto dto, SurveillanceReport existingReport, SurveillanceReportDto existingDto) { + @Override + protected SurveillanceReportReferenceDto toRefDto(SurveillanceReport surveillanceReport) { + return toReferenceDto(surveillanceReport); + } + + @Override + protected void pseudonymizeDto(SurveillanceReport source, SurveillanceReportDto dto, Pseudonymizer pseudonymizer, boolean inJurisdiction) { + User currentUser = userService.getCurrentUser(); + + pseudonymizer.pseudonymizeDto( + SurveillanceReportDto.class, + dto, + inJurisdiction, + (reportDto) -> pseudonymizer.pseudonymizeUser(source.getReportingUser(), currentUser, reportDto::setReportingUser)); + } + + @Override + protected void restorePseudonymizedDto( + SurveillanceReportDto dto, + SurveillanceReportDto existingDto, + SurveillanceReport existingReport, + Pseudonymizer pseudonymizer) { if (existingDto != null) { boolean inJurisdiction = service.inJurisdictionOrOwned(existingReport); User currentUser = userService.getCurrentUser(); - Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService::hasRight); - - pseudonymizer.restoreUser(existingReport.getCreatingUser(), currentUser, dto, dto::setCreatingUser); + pseudonymizer.restoreUser(existingReport.getReportingUser(), currentUser, dto, dto::setReportingUser); pseudonymizer.restorePseudonymizedValues(SurveillanceReportDto.class, dto, existingDto, inJurisdiction); } } - public SurveillanceReport fromDto(@NotNull SurveillanceReportDto source, boolean checkChangeDate) { - SurveillanceReport target = - DtoHelper.fillOrBuildEntity(source, service.getByUuid(source.getUuid()), SurveillanceReport::new, checkChangeDate); + @Override + @RightsAllowed({ + UserRight._CASE_EDIT, + UserRight._SYSTEM }) + public void delete(String surveillanceReportUuid) { + SurveillanceReport report = service.getByUuid(surveillanceReportUuid); + + ExternalMessageDto associatedMessage = externalMessageFacade.getForSurveillanceReport(toRefDto(report)); + if (associatedMessage != null) { + associatedMessage.setSurveillanceReport(null); + externalMessageFacade.save(associatedMessage); + } + service.deletePermanent(report); + } + + public SurveillanceReportDto toDto(SurveillanceReport source) { + if (source == null) { + return null; + } + + SurveillanceReportDto target = new SurveillanceReportDto(); + DtoHelper.fillDto(target, source); target.setReportingType(source.getReportingType()); target.setExternalId(source.getExternalId()); - target.setCreatingUser(userService.getByReferenceDto(source.getCreatingUser())); + target.setReportingUser(source.getReportingUser() == null ? null : source.getReportingUser().toReference()); target.setReportDate(source.getReportDate()); target.setDateOfDiagnosis(source.getDateOfDiagnosis()); - target.setFacilityRegion(regionService.getByReferenceDto(source.getFacilityRegion())); - target.setFacilityDistrict(districtService.getByReferenceDto(source.getFacilityDistrict())); + target.setFacilityRegion(RegionFacadeEjb.toReferenceDto(source.getFacilityRegion())); + target.setFacilityDistrict(DistrictFacadeEjb.toReferenceDto(source.getFacilityDistrict())); target.setFacilityType(source.getFacilityType()); - target.setFacility(facilityService.getByReferenceDto(source.getFacility())); + target.setFacility(FacilityFacadeEjb.toReferenceDto(source.getFacility())); target.setFacilityDetails(source.getFacilityDetails()); target.setNotificationDetails(source.getNotificationDetails()); - target.setCaze(caseService.getByReferenceDto(source.getCaze())); + target.setCaze(CaseFacadeEjb.toReferenceDto(source.getCaze())); + + target.setSormasToSormasOriginInfo(SormasToSormasOriginInfoFacadeEjb.toDto(source.getSormasToSormasOriginInfo())); + target.setOwnershipHandedOver(source.getSormasToSormasShares().stream().anyMatch(ShareInfoHelper::isOwnerShipHandedOver)); return target; } + @RightsAllowed(UserRight._CASE_EDIT) + public SurveillanceReportDto saveSurveillanceReport(SurveillanceReportDto dto, boolean checkChangeDate, boolean internal) { + + SurveillanceReport existingReport = service.getByUuid(dto.getUuid()); + SurveillanceReportDto existingReportDto = toDto(existingReport); + + if (internal && existingReport != null && !service.isEditAllowed(existingReport)) { + throw new AccessDeniedException(I18nProperties.getString(Strings.errorSurveillanceReportNotEditable)); + } + + Pseudonymizer pseudonymizer = createPseudonymizer(); + restorePseudonymizedDto(dto, existingReportDto, existingReport, pseudonymizer); + + validate(dto); + + SurveillanceReport report = fillOrBuildEntity(dto, existingReport, checkChangeDate); + + service.ensurePersisted(report); + + onReportChanged(report, internal); + + return toPseudonymizedDto(report); + } + + @Override + public List getByCaseUuids(List caseUuids) { + return toPseudonymizedDtos(service.getByCaseUuids(caseUuids)); + } + + @RightsAllowed(UserRight._CASE_EDIT) + public void onReportChanged(SurveillanceReport report, boolean syncShares) { + if (syncShares && sormasToSormasFacade.isFeatureConfigured()) { + syncSharesAsync(report); + } + } + + private void syncSharesAsync(SurveillanceReport report) { + executorService.schedule(() -> { + try { + sormasToSormasCaseFacade.syncShares(new ShareTreeCriteria(report.getCaze().getUuid())); + } catch (Exception e) { + logger.error("Failed to sync shares of SurveillanceReport", e); + } + }, 5, TimeUnit.SECONDS); + } + @LocalBean @Stateless public static class SurveillanceReportFacadeEjbLocal extends SurveillanceReportFacadeEjb { + public SurveillanceReportFacadeEjbLocal() { + super(); + } + + @Inject + public SurveillanceReportFacadeEjbLocal(SurveillanceReportService service, UserService userService) { + super(service, userService); + } } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportService.java index 1921730d928..2af107c6a83 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportService.java @@ -97,4 +97,8 @@ private Predicate inJurisdictionOrOwned(CriteriaBuilder cb, CriteriaQuery que return caseService.inJurisdictionOrOwned(new CaseQueryContext(cb, query, new CaseJoins(from.join(SurveillanceReport.CAZE)))); } + + public boolean isEditAllowed(SurveillanceReport report) { + return caseService.isEditAllowed(report.getCaze()); + } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageFacadeEjb.java index b6cd9e2d665..43cf395b336 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/externalmessage/ExternalMessageFacadeEjb.java @@ -64,6 +64,7 @@ import de.symeda.sormas.api.utils.ValidationRuntimeException; import de.symeda.sormas.backend.caze.CaseService; import de.symeda.sormas.backend.caze.surveillancereport.SurveillanceReport; +import de.symeda.sormas.backend.caze.surveillancereport.SurveillanceReportFacadeEjb; import de.symeda.sormas.backend.caze.surveillancereport.SurveillanceReportService; import de.symeda.sormas.backend.common.ConfigFacadeEjb; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; @@ -258,7 +259,7 @@ public ExternalMessageDto toDto(ExternalMessage source) { target.setSampleReports(source.getSampleReports().stream().map(sampleReportFacade::toDto).collect(toList())); } if (source.getSurveillanceReport() != null) { - target.setSurveillanceReport(source.getSurveillanceReport().toReference()); + target.setSurveillanceReport(SurveillanceReportFacadeEjb.toReferenceDto(source.getSurveillanceReport())); } if (source.getAssignee() != null) { target.setAssignee(source.getAssignee().toReference()); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/AbstractSormasToSormasInterface.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/AbstractSormasToSormasInterface.java index bcf194ab3b7..e1e66d3e5fc 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/AbstractSormasToSormasInterface.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/AbstractSormasToSormasInterface.java @@ -42,6 +42,7 @@ import org.slf4j.LoggerFactory; import de.symeda.sormas.api.caze.CaseDataDto; +import de.symeda.sormas.api.caze.surveillancereport.SurveillanceReportDto; import de.symeda.sormas.api.contact.ContactDto; import de.symeda.sormas.api.event.EventDto; import de.symeda.sormas.api.event.EventParticipantDto; @@ -80,6 +81,8 @@ import de.symeda.sormas.api.utils.DataHelper; import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.caze.CaseService; +import de.symeda.sormas.backend.caze.surveillancereport.SurveillanceReport; +import de.symeda.sormas.backend.caze.surveillancereport.SurveillanceReportService; import de.symeda.sormas.backend.common.AbstractCoreAdoService; import de.symeda.sormas.backend.common.ConfigFacadeEjb; import de.symeda.sormas.backend.common.CoreAdo; @@ -173,6 +176,8 @@ public abstract class AbstractSormasToSormasInterface entityUuids, SormasToSormasOptionsDto op if (s.getSample() != null) { sormasToSormasEntitiesHelper.updateSampleOnShare(s.getSample(), s); } + + if (s.getSurveillanceReport() != null) { + sormasToSormasEntitiesHelper.updateSurveillanceReportOnShare(s.getSurveillanceReport(), s); + } }); entities.forEach(e -> { SormasToSormasOriginInfo entityOriginInfo = e.getSormasToSormasOriginInfo(); @@ -582,13 +595,28 @@ private ShareDataExistingEntities loadExistingEntities(SormasToSormasDto receive .collect(Collectors.toMap(Immunization::getUuid, Function.identity())); } + Map existingReports = Collections.emptyMap(); + if (CollectionUtils.isNotEmpty(receivedData.getSurveillanceReports())) { + existingReports = + surveillanceReportService + .getByUuids( + receivedData.getSurveillanceReports() + .stream() + .map(SormasToSormasEntityDto::getEntity) + .map(SurveillanceReportDto::getUuid) + .collect(Collectors.toList())) + .stream() + .collect(Collectors.toMap(SurveillanceReport::getUuid, Function.identity())); + } + return new ShareDataExistingEntities( existingCases, existingContacts, existingEvents, existingEventParticipants, existingSamples, - existingImmunizations); + existingImmunizations, + existingReports); } private ValidationErrorGroup buildEntityValidationGroupName(String uuid) { @@ -926,6 +954,7 @@ private void addOptionsToShareRequestInfo(ShareRequestInfo requestInfo, SormasTo requestInfo.setWithSamples(options.isWithSamples()); requestInfo.setWithEventParticipants(options.isWithEventParticipants()); requestInfo.setWithImmunizations(options.isWithImmunizations()); + requestInfo.setWithSurveillanceReports(options.isWithSurveillanceReports()); requestInfo.setPseudonymizedPersonalData(options.isPseudonymizeData()); requestInfo.setPseudonymizedSensitiveData(options.isPseudonymizeData()); requestInfo.setComment(options.getComment()); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/SormasToSormasFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/SormasToSormasFacadeEjb.java index a16973d4e3a..6b986e27ebe 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/SormasToSormasFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/SormasToSormasFacadeEjb.java @@ -30,6 +30,7 @@ import javax.inject.Inject; import javax.transaction.Transactional; +import de.symeda.sormas.backend.caze.surveillancereport.SurveillanceReport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -275,6 +276,7 @@ public void requestAccepted(SormasToSormasEncryptedDataDto encryptedAcceptData) updateOriginInfoOnShareAccepted(s.getEvent(), s); updateOriginInfoOnShareAccepted(s.getEventParticipant(), s); updateSampleOnShareAccepted(s); + updateSurveillanceReportOnShareAccepted(s); updateOriginInfoOnShareAccepted(s.getImmunization(), s); }); shareRequestInfoService.ensurePersisted(requestInfo); @@ -313,6 +315,15 @@ private void updateSampleOnShareAccepted(SormasToSormasShareInfo s) { } } + private void updateSurveillanceReportOnShareAccepted(SormasToSormasShareInfo s) { + SurveillanceReport report = s.getSurveillanceReport(); + + if (report != null) { + updateOriginInfoOnShareAccepted(report, s); + sormasToSormasEntitiesHelper.updateSurveillanceReportOnShare(s.getSurveillanceReport(), s); + } + } + private void updateOriginInfoOnShareAccepted(SormasToSormasShareable entity, SormasToSormasShareInfo shareInfo) { if (entity != null) { SormasToSormasOriginInfo originInfo = entity.getSormasToSormasOriginInfo(); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/ValidationHelper.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/ValidationHelper.java index 926b21281fa..e3adc15171e 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/ValidationHelper.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/ValidationHelper.java @@ -19,7 +19,7 @@ import java.util.List; import java.util.function.Supplier; -import de.symeda.sormas.api.uuid.HasUuid; +import de.symeda.sormas.api.caze.surveillancereport.SurveillanceReportDto; import de.symeda.sormas.api.externalmessage.ExternalMessageDto; import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.i18n.Validations; @@ -32,6 +32,7 @@ import de.symeda.sormas.api.sormastosormas.validation.ValidationErrors; import de.symeda.sormas.api.utils.DataHelper; import de.symeda.sormas.api.utils.ValidationRuntimeException; +import de.symeda.sormas.api.uuid.HasUuid; public class ValidationHelper { @@ -71,24 +72,31 @@ public static ValidationErrorGroup buildImmunizationValidationGroupName(Immuniza return buildValidationGroupName(Captions.Immunization_uuid, immunization); } + public static ValidationErrorGroup buildSurveillanceReportValidationGroupName(SurveillanceReportDto report) { + return buildValidationGroupName(Captions.SurveillanceReport_uuid, report); + } + public static ValidationErrorGroup buildExternalMessageValidationGroupName(ExternalMessageDto externalMessageDto) { return buildValidationGroupName(Captions.ExternalMessage, externalMessageDto); } public static T handleValidationError( - Supplier saveOperation, - String validationGroupCaption, - ValidationErrorGroup parentValidationGroup, - HasUuid context) - throws SormasToSormasValidationException { + Supplier saveOperation, + String validationGroupCaption, + ValidationErrorGroup parentValidationGroup, + HasUuid context) + throws SormasToSormasValidationException { try { return saveOperation.get(); } catch (ValidationRuntimeException exception) { List errors = new ArrayList<>(); ValidationErrors validationErrors = new ValidationErrors(parentValidationGroup); validationErrors.add( - new ValidationErrorGroup(validationGroupCaption), - new ValidationErrorMessage(Validations.sormasToSormasSaveException, String.format("%s (UUID: %s)", validationGroupCaption, context.getUuid()), exception.getMessage())); + new ValidationErrorGroup(validationGroupCaption), + new ValidationErrorMessage( + Validations.sormasToSormasSaveException, + String.format("%s (UUID: %s)", validationGroupCaption, context.getUuid()), + exception.getMessage())); errors.add(validationErrors); throw new SormasToSormasValidationException(errors, exception); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ProcessedEntitiesPersister.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ProcessedEntitiesPersister.java index 68bfc40328d..e482878fb2f 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ProcessedEntitiesPersister.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ProcessedEntitiesPersister.java @@ -33,6 +33,7 @@ import de.symeda.sormas.api.sormastosormas.entities.event.SormasToSormasEventParticipantDto; import de.symeda.sormas.api.sormastosormas.entities.immunization.SormasToSormasImmunizationDto; import de.symeda.sormas.api.sormastosormas.entities.sample.SormasToSormasSampleDto; +import de.symeda.sormas.api.sormastosormas.entities.surveillancereport.SormasToSormasSurveillanceReportDto; import de.symeda.sormas.api.sormastosormas.validation.SormasToSormasValidationException; import de.symeda.sormas.backend.caze.CaseFacadeEjb; import de.symeda.sormas.backend.contact.ContactFacadeEjb; @@ -43,6 +44,7 @@ import de.symeda.sormas.backend.sormastosormas.entities.eventparticipant.ProcessedEventParticipantDataPersister; import de.symeda.sormas.backend.sormastosormas.entities.immunization.ProcessedImmunizationDataPersister; import de.symeda.sormas.backend.sormastosormas.entities.sample.ProcessedSampleDataPersister; +import de.symeda.sormas.backend.sormastosormas.entities.surveillancereport.ProcessedSurveillanceReportDataPersister; @Stateless @LocalBean @@ -60,6 +62,8 @@ public class ProcessedEntitiesPersister { private ProcessedEventParticipantDataPersister eventParticipantDataPersister; @EJB private ProcessedImmunizationDataPersister immunizationDataPersister; + @EJB + private ProcessedSurveillanceReportDataPersister surveillanceReportDataPersister; @EJB private CaseFacadeEjb.CaseFacadeEjbLocal caseFacade; @@ -113,6 +117,14 @@ public void persistSharedData(SormasToSormasDto processedData, SormasToSormasOri immunizationDataPersister.persistSharedData(s, originInfo, existingEntities.getImmunizations().get(s.getEntity().getUuid())); } } + + List reports = processedData.getSurveillanceReports(); + if (CollectionUtils.isNotEmpty(reports)) { + for (SormasToSormasSurveillanceReportDto r : reports) { + surveillanceReportDataPersister + .persistSharedData(r, originInfo, existingEntities.getSurveillanceReports().get(r.getEntity().getUuid())); + } + } } public DuplicateResult checkForSimilarEntities(SormasToSormasDto processedData, ShareDataExistingEntities existingEntities) { @@ -186,6 +198,14 @@ public void persistSyncData( } } + List reports = processedData.getSurveillanceReports(); + if (CollectionUtils.isNotEmpty(reports)) { + for (SormasToSormasSurveillanceReportDto r : reports) { + surveillanceReportDataPersister + .persistSyncData(r, originInfoDto, existingEntities.getSurveillanceReports().get(r.getEntity().getUuid())); + } + } + if (CollectionUtils.isNotEmpty(cases)) { caseFacade.syncSharesAsync(shareTreeCriteria); } else if (CollectionUtils.isNotEmpty(contacts)) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ReceivedEntitiesProcessor.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ReceivedEntitiesProcessor.java index 121c24e056b..849f229f3d8 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ReceivedEntitiesProcessor.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ReceivedEntitiesProcessor.java @@ -35,6 +35,7 @@ import de.symeda.sormas.api.sormastosormas.entities.event.SormasToSormasEventParticipantDto; import de.symeda.sormas.api.sormastosormas.entities.immunization.SormasToSormasImmunizationDto; import de.symeda.sormas.api.sormastosormas.entities.sample.SormasToSormasSampleDto; +import de.symeda.sormas.api.sormastosormas.entities.surveillancereport.SormasToSormasSurveillanceReportDto; import de.symeda.sormas.api.sormastosormas.validation.ValidationErrorGroup; import de.symeda.sormas.api.sormastosormas.validation.ValidationErrorMessage; import de.symeda.sormas.api.sormastosormas.validation.ValidationErrors; @@ -46,6 +47,7 @@ import de.symeda.sormas.backend.sormastosormas.entities.eventparticipant.ReceivedEventParticipantProcessor; import de.symeda.sormas.backend.sormastosormas.entities.immunization.ReceivedImmunizationProcessor; import de.symeda.sormas.backend.sormastosormas.entities.sample.ReceivedSampleProcessor; +import de.symeda.sormas.backend.sormastosormas.entities.surveillancereport.ReceivedSurveillanceReportProcessor; import de.symeda.sormas.backend.sormastosormas.share.ShareRequestData; @Stateless @@ -64,6 +66,8 @@ public class ReceivedEntitiesProcessor { private ReceivedEventParticipantProcessor eventParticipantProcessor; @EJB private ReceivedImmunizationProcessor immunizationProcessor; + @EJB + private ReceivedSurveillanceReportProcessor surveillanceReportProcessor; public List processReceivedData(SormasToSormasDto receivedData, ShareDataExistingEntities existingEntities) { List validationErrors = new ArrayList<>(); @@ -152,6 +156,19 @@ public List processReceivedData(SormasToSormasDto receivedData }); } + List reports = receivedData.getSurveillanceReports(); + if (CollectionUtils.isNotEmpty(reports)) { + reports.forEach(r -> { + ValidationErrors immunizationErrors = surveillanceReportProcessor + .processReceivedData(r, existingEntities.getSurveillanceReports().get(r.getEntity().getUuid()), originInfo); + + if (immunizationErrors.hasError()) { + validationErrors + .add(new ValidationErrors(ValidationHelper.buildSurveillanceReportValidationGroupName(r.getEntity()), immunizationErrors)); + } + }); + } + return validationErrors; } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ShareDataBuilder.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ShareDataBuilder.java index 0589613f1d6..6cfa9e72b1f 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ShareDataBuilder.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ShareDataBuilder.java @@ -32,6 +32,7 @@ import de.symeda.sormas.api.sormastosormas.entities.event.SormasToSormasEventParticipantDto; import de.symeda.sormas.api.sormastosormas.entities.immunization.SormasToSormasImmunizationDto; import de.symeda.sormas.api.sormastosormas.entities.sample.SormasToSormasSampleDto; +import de.symeda.sormas.api.sormastosormas.entities.surveillancereport.SormasToSormasSurveillanceReportDto; import de.symeda.sormas.api.sormastosormas.share.incoming.SormasToSormasCasePreview; import de.symeda.sormas.api.sormastosormas.share.incoming.SormasToSormasContactPreview; import de.symeda.sormas.api.sormastosormas.share.incoming.SormasToSormasEventParticipantPreview; @@ -44,6 +45,7 @@ import de.symeda.sormas.backend.sormastosormas.entities.eventparticipant.EventParticipantShareDataBuilder; import de.symeda.sormas.backend.sormastosormas.entities.immunization.ImmunizationShareDataBuilder; import de.symeda.sormas.backend.sormastosormas.entities.sample.SampleShareDataBuilder; +import de.symeda.sormas.backend.sormastosormas.entities.surveillancereport.SurveillanceReportShareDataBuilder; import de.symeda.sormas.backend.sormastosormas.share.ShareDataBuilderHelper; import de.symeda.sormas.backend.sormastosormas.share.incoming.ShareRequestPreviews; import de.symeda.sormas.backend.sormastosormas.share.outgoing.ShareRequestInfo; @@ -66,6 +68,9 @@ public class ShareDataBuilder { private EventParticipantShareDataBuilder eventParticipantShareDataBuilder; @EJB private ImmunizationShareDataBuilder immunizationShareDataBuilder; + + @EJB + private SurveillanceReportShareDataBuilder surveillanceReportShareDataBuilder; @EJB private ShareDataBuilderHelper shareDataBuilderHelper; @@ -87,6 +92,7 @@ public SormasToSormasDto buildShareData( List events = new ArrayList<>(); List eventParticipants = new ArrayList<>(); List immunizations = new ArrayList<>(); + List reports = new ArrayList<>(); List validationErrors = new ArrayList<>(); @@ -139,6 +145,14 @@ public SormasToSormasDto buildShareData( validationErrors.addAll(e.getErrors()); } } + + if (s.getSurveillanceReport() != null) { + try { + reports.add(surveillanceReportShareDataBuilder.buildShareData(s.getSurveillanceReport(), requestInfo, s.isOwnershipHandedOver())); + } catch (SormasToSormasValidationException e) { + validationErrors.addAll(e.getErrors()); + } + } }); if (!validationErrors.isEmpty()) { @@ -153,6 +167,7 @@ public SormasToSormasDto buildShareData( dto.setEvents(events); dto.setEventParticipants(eventParticipants); dto.setImmunizations(immunizations); + dto.setSurveillanceReports(reports); return dto; } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ShareDataExistingEntities.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ShareDataExistingEntities.java index 9b0db59199f..f34b5c2149a 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ShareDataExistingEntities.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ShareDataExistingEntities.java @@ -18,6 +18,7 @@ import java.util.Map; import de.symeda.sormas.backend.caze.Case; +import de.symeda.sormas.backend.caze.surveillancereport.SurveillanceReport; import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.event.Event; import de.symeda.sormas.backend.event.EventParticipant; @@ -32,6 +33,7 @@ public class ShareDataExistingEntities { private final Map eventParticipants; private final Map samples; private final Map immunizations; + private final Map surveillanceReports; public ShareDataExistingEntities( Map cases, @@ -39,13 +41,15 @@ public ShareDataExistingEntities( Map events, Map eventParticipants, Map samples, - Map immunizations) { + Map immunizations, + Map surveillanceReports) { this.cases = cases; this.contacts = contacts; this.events = events; this.eventParticipants = eventParticipants; this.samples = samples; this.immunizations = immunizations; + this.surveillanceReports = surveillanceReports; } public Map getCases() { @@ -71,4 +75,8 @@ public Map getSamples() { public Map getImmunizations() { return immunizations; } + + public Map getSurveillanceReports() { + return surveillanceReports; + } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/SormasToSormasEntitiesHelper.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/SormasToSormasEntitiesHelper.java index afe60cb6358..a8240c9c887 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/SormasToSormasEntitiesHelper.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/SormasToSormasEntitiesHelper.java @@ -19,6 +19,7 @@ import de.symeda.sormas.api.person.OccupationType; import de.symeda.sormas.api.person.PersonDto; import de.symeda.sormas.backend.caze.Case; +import de.symeda.sormas.backend.caze.surveillancereport.SurveillanceReport; import de.symeda.sormas.backend.common.ConfigFacadeEjb.ConfigFacadeEjbLocal; import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.customizableenum.CustomizableEnumFacadeEjb; @@ -152,4 +153,12 @@ public void updateSampleOnShare(Sample sample, SormasToSormasShareInfo sareInfo) }); } } + + public void updateSurveillanceReportOnShare(SurveillanceReport surveillanceReport, SormasToSormasShareInfo sareInfo) { + if (sareInfo.isOwnershipHandedOver()) { + if (surveillanceReport.getExternalMessage() != null) { + surveillanceReport.getExternalMessage().setStatus(ExternalMessageStatus.FORWARDED); + } + } + } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/caze/SormasToSormasCaseFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/caze/SormasToSormasCaseFacadeEjb.java index b8a1b51cc85..80ce48bc128 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/caze/SormasToSormasCaseFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/caze/SormasToSormasCaseFacadeEjb.java @@ -219,7 +219,20 @@ protected List getOrCreateShareInfos(Case caze, SormasT .orElseGet(() -> ShareInfoHelper.createShareInfo(organizationId, i, SormasToSormasShareInfo::setImmunization, options))); } - return Stream.of(Stream.of(cazeShareInfo), contactShareInfos, sampleShareInfos, immunizationShareInfos) + Stream reportShareInfos = Stream.empty(); + if (options.isWithSurveillanceReports()) { + reportShareInfos = caze.getSurveillanceReports() + .stream() + .map( + r -> r.getSormasToSormasShares() + .stream() + .filter(share -> share.getOrganizationId().equals(organizationId)) + .findFirst() + .orElseGet( + () -> ShareInfoHelper.createShareInfo(organizationId, r, SormasToSormasShareInfo::setSurveillanceReport, options))); + } + + return Stream.of(Stream.of(cazeShareInfo), contactShareInfos, sampleShareInfos, immunizationShareInfos, reportShareInfos) .flatMap(Function.identity()) .collect(Collectors.toList()); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/sample/SampleShareDataBuilder.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/sample/SampleShareDataBuilder.java index f842ece028f..6d3d7e31fb4 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/sample/SampleShareDataBuilder.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/sample/SampleShareDataBuilder.java @@ -24,7 +24,6 @@ import javax.ejb.Stateless; import javax.inject.Inject; -import de.symeda.sormas.api.externalmessage.ExternalMessageDto; import de.symeda.sormas.api.sample.AdditionalTestDto; import de.symeda.sormas.api.sample.PathogenTestDto; import de.symeda.sormas.api.sample.SampleDto; @@ -32,8 +31,6 @@ import de.symeda.sormas.api.sormastosormas.entities.sample.SormasToSormasSampleDto; import de.symeda.sormas.api.sormastosormas.share.incoming.PreviewNotImplementedDto; import de.symeda.sormas.api.utils.ValidationRuntimeException; -import de.symeda.sormas.backend.externalmessage.ExternalMessage; -import de.symeda.sormas.backend.externalmessage.ExternalMessageFacadeEjb; import de.symeda.sormas.backend.sample.AdditionalTestFacadeEjb; import de.symeda.sormas.backend.sample.PathogenTestFacadeEjb; import de.symeda.sormas.backend.sample.Sample; @@ -55,8 +52,6 @@ public class SampleShareDataBuilder @EJB private AdditionalTestFacadeEjb.AdditionalTestFacadeEjbLocal additionalTestFacade; @EJB - private ExternalMessageFacadeEjb.ExternalMessageFacadeEjbLocal externalMessageFacade; - @EJB private ShareDataBuilderHelper dataBuilderHelper; @Inject @@ -84,16 +79,11 @@ protected SormasToSormasSampleDto doBuildShareData(Sample sample, ShareRequestIn List externalMessages = Collections.emptyList(); if (ownerShipHandedOver) { - externalMessages = sample.getSampleReports().stream().map(r -> { - ExternalMessage m = r.getLabMessage(); - ExternalMessageDto externalMessageDto = externalMessageFacade.toDto(m); - externalMessageDto.setAssignee(null); - // Cleanup surveillance report link until sending reports are implemented by #10247 - // TODO - remove this lie when implementing #10247 - externalMessageDto.setSurveillanceReport(null); - - return new SormasToSormasExternalMessageDto(externalMessageDto); - }).collect(Collectors.toList()); + externalMessages = + sample.getSampleReports() + .stream() + .map(s -> dataBuilderHelper.getExternalMessageDto(s.getLabMessage(), requestInfo)) + .collect(Collectors.toList()); } return new SormasToSormasSampleDto(sampleDto, pathogenTests, additionalTests, externalMessages); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/surveillancereport/ProcessedSurveillanceReportDataPersister.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/surveillancereport/ProcessedSurveillanceReportDataPersister.java new file mode 100644 index 00000000000..2855da1c74b --- /dev/null +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/surveillancereport/ProcessedSurveillanceReportDataPersister.java @@ -0,0 +1,91 @@ +/* + * SORMAS® - Surveillance Outbreak Response Management & Analysis System + * Copyright © 2016-2022 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.symeda.sormas.backend.sormastosormas.entities.surveillancereport; + +import static de.symeda.sormas.backend.sormastosormas.ValidationHelper.buildSurveillanceReportValidationGroupName; +import static de.symeda.sormas.backend.sormastosormas.ValidationHelper.buildValidationGroupName; +import static de.symeda.sormas.backend.sormastosormas.ValidationHelper.handleValidationError; + +import javax.ejb.EJB; +import javax.ejb.LocalBean; +import javax.ejb.Stateless; + +import de.symeda.sormas.api.caze.surveillancereport.SurveillanceReportDto; +import de.symeda.sormas.api.externalmessage.ExternalMessageDto; +import de.symeda.sormas.api.i18n.Captions; +import de.symeda.sormas.api.sormastosormas.entities.surveillancereport.SormasToSormasSurveillanceReportDto; +import de.symeda.sormas.api.sormastosormas.validation.SormasToSormasValidationException; +import de.symeda.sormas.backend.caze.surveillancereport.SurveillanceReport; +import de.symeda.sormas.backend.caze.surveillancereport.SurveillanceReportFacadeEjb.SurveillanceReportFacadeEjbLocal; +import de.symeda.sormas.backend.externalmessage.ExternalMessageFacadeEjb; +import de.symeda.sormas.backend.sormastosormas.data.processed.ProcessedDataPersister; +import de.symeda.sormas.backend.sormastosormas.origin.SormasToSormasOriginInfoFacadeEjb; +import de.symeda.sormas.backend.sormastosormas.origin.SormasToSormasOriginInfoFacadeEjb.SormasToSormasOriginInfoFacadeEjbLocal; +import de.symeda.sormas.backend.sormastosormas.share.outgoing.SormasToSormasShareInfo; +import de.symeda.sormas.backend.sormastosormas.share.outgoing.SormasToSormasShareInfoService; + +@Stateless +@LocalBean +public class ProcessedSurveillanceReportDataPersister + extends ProcessedDataPersister { + + @EJB + private SormasToSormasShareInfoService shareInfoService; + + @EJB + private SormasToSormasOriginInfoFacadeEjbLocal originInfoFacade; + + @EJB + private SurveillanceReportFacadeEjbLocal surveillanceReportFacade; + @EJB + private ExternalMessageFacadeEjb.ExternalMessageFacadeEjbLocal externalMessageFacade; + + @Override + protected SormasToSormasShareInfoService getShareInfoService() { + return shareInfoService; + } + + @Override + protected SormasToSormasOriginInfoFacadeEjb getOriginInfoFacade() { + return originInfoFacade; + } + + @Override + protected void persistSharedData(SormasToSormasSurveillanceReportDto processedData, SurveillanceReport existingEntity, boolean isSync) + throws SormasToSormasValidationException { + SurveillanceReportDto report = processedData.getEntity(); + + handleValidationError( + () -> surveillanceReportFacade.saveSurveillanceReport(report, false, false), + Captions.Immunization, + buildSurveillanceReportValidationGroupName(report), + report); + + if (processedData.getExternalMessage() != null) { + ExternalMessageDto externalMessage = processedData.getExternalMessage().getEntity(); + handleValidationError( + () -> externalMessageFacade.save(externalMessage, false, false), + Captions.ExternalMessage, + buildValidationGroupName(Captions.ExternalMessage, externalMessage), + externalMessage); + } + } + + @Override + protected SormasToSormasShareInfo getShareInfoByEntityAndOrganization(SurveillanceReportDto entity, String organizationId) { + return shareInfoService.getBySurveillanceReportAndOrganization(entity.getUuid(), organizationId); + } +} diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/surveillancereport/ReceivedSurveillanceReportProcessor.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/surveillancereport/ReceivedSurveillanceReportProcessor.java new file mode 100644 index 00000000000..fcead95d457 --- /dev/null +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/surveillancereport/ReceivedSurveillanceReportProcessor.java @@ -0,0 +1,81 @@ +/* + * SORMAS® - Surveillance Outbreak Response Management & Analysis System + * Copyright © 2016-2022 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.symeda.sormas.backend.sormastosormas.entities.surveillancereport; + +import javax.ejb.EJB; +import javax.ejb.LocalBean; +import javax.ejb.Stateless; +import javax.inject.Inject; + +import de.symeda.sormas.api.caze.surveillancereport.SurveillanceReportDto; +import de.symeda.sormas.api.i18n.Captions; +import de.symeda.sormas.api.i18n.Validations; +import de.symeda.sormas.api.sormastosormas.SormasToSormasOriginInfoDto; +import de.symeda.sormas.api.sormastosormas.entities.surveillancereport.SormasToSormasSurveillanceReportDto; +import de.symeda.sormas.api.sormastosormas.share.incoming.PreviewNotImplementedDto; +import de.symeda.sormas.api.sormastosormas.validation.ValidationErrors; +import de.symeda.sormas.backend.caze.surveillancereport.SurveillanceReport; +import de.symeda.sormas.backend.caze.surveillancereport.SurveillanceReportFacadeEjb.SurveillanceReportFacadeEjbLocal; +import de.symeda.sormas.backend.caze.surveillancereport.SurveillanceReportService; +import de.symeda.sormas.backend.common.ConfigFacadeEjb; +import de.symeda.sormas.backend.sormastosormas.data.received.ReceivedDataProcessor; +import de.symeda.sormas.backend.user.UserService; + +@Stateless +@LocalBean +public class ReceivedSurveillanceReportProcessor + extends + ReceivedDataProcessor { + + @EJB + private SurveillanceReportFacadeEjbLocal surveillanceReportFacade; + + public ReceivedSurveillanceReportProcessor() { + } + + @Inject + protected ReceivedSurveillanceReportProcessor( + SurveillanceReportService service, + UserService userService, + ConfigFacadeEjb.ConfigFacadeEjbLocal configFacade, + SormasToSormasSurveillanceReportDtoValidator validator) { + super(service, userService, configFacade, validator); + } + + @Override + public void handleReceivedData( + SormasToSormasSurveillanceReportDto sharedData, + SurveillanceReport existingData, + SormasToSormasOriginInfoDto originInfo) { + updateReportingUser(sharedData.getEntity(), existingData); + handleIgnoredProperties(sharedData.getEntity(), surveillanceReportFacade.toDto(existingData)); + } + + @Override + public ValidationErrors processReceivedPreview(PreviewNotImplementedDto sharedPreview) { + throw new RuntimeException("SurveillanceReport preview not yet implemented"); + } + + @Override + public ValidationErrors existsNotShared(String uuid) { + return existsNotShared( + uuid, + SurveillanceReport.SORMAS_TO_SORMAS_ORIGIN_INFO, + SurveillanceReport.SORMAS_TO_SORMAS_SHARES, + Captions.SurveillanceReport, + Validations.sormasToSormasSurveillanceReportExists); + } +} diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/surveillancereport/SormasToSormasSurveillanceReportDtoValidator.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/surveillancereport/SormasToSormasSurveillanceReportDtoValidator.java new file mode 100644 index 00000000000..307d6dcc461 --- /dev/null +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/surveillancereport/SormasToSormasSurveillanceReportDtoValidator.java @@ -0,0 +1,80 @@ +/* + * SORMAS® - Surveillance Outbreak Response Management & Analysis System + * Copyright © 2016-2022 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.symeda.sormas.backend.sormastosormas.entities.surveillancereport; + +import static de.symeda.sormas.backend.sormastosormas.ValidationHelper.buildSurveillanceReportValidationGroupName; + +import javax.ejb.EJB; +import javax.ejb.LocalBean; +import javax.ejb.Stateless; +import javax.inject.Inject; + +import de.symeda.sormas.api.caze.surveillancereport.SurveillanceReportDto; +import de.symeda.sormas.api.i18n.Captions; +import de.symeda.sormas.api.sormastosormas.entities.externalmessage.SormasToSormasExternalMessageDto; +import de.symeda.sormas.api.sormastosormas.entities.surveillancereport.SormasToSormasSurveillanceReportDto; +import de.symeda.sormas.api.sormastosormas.share.incoming.PreviewNotImplementedDto; +import de.symeda.sormas.api.sormastosormas.validation.ValidationErrors; +import de.symeda.sormas.backend.sormastosormas.data.infra.InfrastructureValidator; +import de.symeda.sormas.backend.sormastosormas.data.validation.SormasToSormasDtoValidator; +import de.symeda.sormas.backend.sormastosormas.data.validation.ValidationDirection; +import de.symeda.sormas.backend.sormastosormas.entities.externalmessage.SormasToSormasExternalMessageDtoValidator; + +@Stateless +@LocalBean +public class SormasToSormasSurveillanceReportDtoValidator + extends SormasToSormasDtoValidator { + + @EJB + private SormasToSormasExternalMessageDtoValidator externalMessageDtoValidator; + + public SormasToSormasSurveillanceReportDtoValidator() { + } + + @Inject + public SormasToSormasSurveillanceReportDtoValidator(InfrastructureValidator infraValidator) { + super(infraValidator); + } + + @Override + public ValidationErrors validate(SormasToSormasSurveillanceReportDto sharedData, ValidationDirection direction) { + final SurveillanceReportDto report = sharedData.getEntity(); + ValidationErrors validationErrors = new ValidationErrors(buildSurveillanceReportValidationGroupName(report)); + + final String groupNameTag = Captions.SurveillanceReport; + infraValidator.validateResponsibleRegion(report.getFacilityRegion(), groupNameTag, validationErrors, report::setFacilityRegion, direction); + infraValidator + .validateResponsibleDistrict(report.getFacilityDistrict(), groupNameTag, validationErrors, report::setFacilityDistrict, direction); + infraValidator + .validateFacility(report.getFacility(), report.getFacilityType(), report.getFacilityDetails(), groupNameTag, validationErrors, f -> { + report.setFacility(f.getEntity()); + report.setFacilityDetails(f.getDetails()); + }); + + SormasToSormasExternalMessageDto externalMessage = sharedData.getExternalMessage(); + if (externalMessage != null) { + validationErrors.addAll(externalMessageDtoValidator.validate(externalMessage, direction)); + } + + return validationErrors; + } + + @Override + public ValidationErrors validatePreview(PreviewNotImplementedDto previewNotImplementedDto, ValidationDirection direction) { + // todo adjust test in InfraValidationSoundnessTest once preview is available for this entity + throw new RuntimeException("SurveillanceReport preview not yet implemented"); + } +} diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/surveillancereport/SurveillanceReportShareDataBuilder.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/surveillancereport/SurveillanceReportShareDataBuilder.java new file mode 100644 index 00000000000..a89c93a6878 --- /dev/null +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/surveillancereport/SurveillanceReportShareDataBuilder.java @@ -0,0 +1,90 @@ +/* + * SORMAS® - Surveillance Outbreak Response Management & Analysis System + * Copyright © 2016-2022 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.symeda.sormas.backend.sormastosormas.entities.surveillancereport; + +import javax.ejb.EJB; +import javax.ejb.LocalBean; +import javax.ejb.Stateless; +import javax.inject.Inject; + +import de.symeda.sormas.api.caze.surveillancereport.SurveillanceReportDto; +import de.symeda.sormas.api.sormastosormas.entities.externalmessage.SormasToSormasExternalMessageDto; +import de.symeda.sormas.api.sormastosormas.entities.surveillancereport.SormasToSormasSurveillanceReportDto; +import de.symeda.sormas.api.sormastosormas.share.incoming.PreviewNotImplementedDto; +import de.symeda.sormas.api.utils.ValidationRuntimeException; +import de.symeda.sormas.backend.caze.surveillancereport.SurveillanceReport; +import de.symeda.sormas.backend.caze.surveillancereport.SurveillanceReportFacadeEjb.SurveillanceReportFacadeEjbLocal; +import de.symeda.sormas.backend.sormastosormas.share.ShareDataBuilder; +import de.symeda.sormas.backend.sormastosormas.share.ShareDataBuilderHelper; +import de.symeda.sormas.backend.sormastosormas.share.outgoing.ShareRequestInfo; +import de.symeda.sormas.backend.util.Pseudonymizer; + +@Stateless +@LocalBean +public class SurveillanceReportShareDataBuilder + extends + ShareDataBuilder { + + @EJB + private SurveillanceReportFacadeEjbLocal surveillanceReportFacade; + @EJB + private ShareDataBuilderHelper dataBuilderHelper; + + public SurveillanceReportShareDataBuilder() { + } + + @Inject + public SurveillanceReportShareDataBuilder(SormasToSormasSurveillanceReportDtoValidator validator) { + super(validator); + } + + @Override + protected SormasToSormasSurveillanceReportDto doBuildShareData( + SurveillanceReport report, + ShareRequestInfo requestInfo, + boolean ownerShipHandedOver) { + Pseudonymizer pseudonymizer = dataBuilderHelper.createPseudonymizer(requestInfo); + SurveillanceReportDto reportDto = getDto(report, pseudonymizer); + + SormasToSormasExternalMessageDto externalMessage = null; + if (ownerShipHandedOver && report.getExternalMessage() != null) { + externalMessage = dataBuilderHelper.getExternalMessageDto(report.getExternalMessage(), requestInfo); + } + + return new SormasToSormasSurveillanceReportDto(reportDto, externalMessage); + } + + @Override + protected SurveillanceReportDto getDto(SurveillanceReport surveillanceReport, Pseudonymizer pseudonymizer) { + SurveillanceReportDto report = surveillanceReportFacade.toPseudonymizedDto(surveillanceReport, pseudonymizer); + // reporting user is not set to null here as it would not pass the validation + // the receiver appears to set it to SORMAS2SORMAS Client anyway + report.setSormasToSormasOriginInfo(null); + dataBuilderHelper.clearIgnoredProperties(report); + + return report; + } + + @Override + protected void doBusinessValidation(SormasToSormasSurveillanceReportDto sormasToSormasSurveillanceReportDto) throws ValidationRuntimeException { + surveillanceReportFacade.validate(sormasToSormasSurveillanceReportDto.getEntity()); + } + + @Override + protected PreviewNotImplementedDto doBuildShareDataPreview(SurveillanceReport data, ShareRequestInfo requestInfo) { + throw new RuntimeException("SurveillanceReport preview not yet implemented"); + } +} diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/origin/SormasToSormasOriginInfo.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/origin/SormasToSormasOriginInfo.java index 6b43e6164e2..a5c2b9a12f2 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/origin/SormasToSormasOriginInfo.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/origin/SormasToSormasOriginInfo.java @@ -70,6 +70,8 @@ public class SormasToSormasOriginInfo extends AbstractDomainObject { private boolean withImmunizations; + private boolean withSurveillanceReports; + private String comment; private SormasToSormasShareRequest request; @@ -167,6 +169,15 @@ public void setWithImmunizations(boolean withImmunizations) { this.withImmunizations = withImmunizations; } + @Column + public boolean isWithSurveillanceReports() { + return withSurveillanceReports; + } + + public void setWithSurveillanceReports(boolean withSurveillanceReports) { + this.withSurveillanceReports = withSurveillanceReports; + } + @OneToOne(mappedBy = "originInfo") public SormasToSormasShareRequest getRequest() { return request; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/origin/SormasToSormasOriginInfoFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/origin/SormasToSormasOriginInfoFacadeEjb.java index 235a8dceb4f..15e9883f7a0 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/origin/SormasToSormasOriginInfoFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/origin/SormasToSormasOriginInfoFacadeEjb.java @@ -58,6 +58,7 @@ public static SormasToSormasOriginInfoDto toDto(SormasToSormasOriginInfo source) target.setWithSamples(source.isWithSamples()); target.setWithEventParticipants(source.isWithEventParticipants()); target.setWithImmunizations(source.isWithImmunizations()); + target.setWithSurveillanceReports(source.isWithSurveillanceReports()); target.setComment(source.getComment()); target.setPseudonymizedData(source.isPseudonymizedData()); @@ -93,6 +94,7 @@ public SormasToSormasOriginInfo fillOrBuildEntity(SormasToSormasOriginInfoDto so target.setWithSamples(source.isWithSamples()); target.setWithEventParticipants(source.isWithEventParticipants()); target.setWithImmunizations(source.isWithImmunizations()); + target.setWithSurveillanceReports(source.isWithSurveillanceReports()); target.setComment(source.getComment()); target.setPseudonymizedData(source.isPseudonymizedData()); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/ShareDataBuilderHelper.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/ShareDataBuilderHelper.java index 9f23fe84bb0..96ed61a0b7e 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/ShareDataBuilderHelper.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/ShareDataBuilderHelper.java @@ -25,6 +25,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import de.symeda.sormas.api.externalmessage.ExternalMessageDto; import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.person.PersonDto; @@ -33,11 +34,14 @@ import de.symeda.sormas.api.sormastosormas.SormasToSormasConfig; import de.symeda.sormas.api.sormastosormas.SormasToSormasOptionsDto; import de.symeda.sormas.api.sormastosormas.SormasToSormasOriginInfoDto; +import de.symeda.sormas.api.sormastosormas.entities.externalmessage.SormasToSormasExternalMessageDto; import de.symeda.sormas.api.sormastosormas.share.incoming.SormasToSormasPersonPreview; import de.symeda.sormas.api.utils.fieldaccess.checkers.PersonalDataFieldAccessChecker; import de.symeda.sormas.api.utils.fieldaccess.checkers.SensitiveDataFieldAccessChecker; import de.symeda.sormas.backend.common.ConfigFacadeEjb; import de.symeda.sormas.backend.contact.ContactFacadeEjb; +import de.symeda.sormas.backend.externalmessage.ExternalMessage; +import de.symeda.sormas.backend.externalmessage.ExternalMessageFacadeEjb; import de.symeda.sormas.backend.location.LocationFacadeEjb; import de.symeda.sormas.backend.person.Person; import de.symeda.sormas.backend.person.PersonFacadeEjb; @@ -58,6 +62,8 @@ public class ShareDataBuilderHelper { private ContactFacadeEjb.ContactFacadeEjbLocal contactFacade; @EJB private ConfigFacadeEjb.ConfigFacadeEjbLocal configFacadeEjb; + @EJB + private ExternalMessageFacadeEjb.ExternalMessageFacadeEjbLocal externalMessageFacade; public Pseudonymizer createPseudonymizer(ShareRequestInfo requestInfo) { Pseudonymizer pseudonymizer = Pseudonymizer.getDefaultNoCheckers(false); @@ -103,6 +109,7 @@ public SormasToSormasOriginInfoDto createSormasToSormasOriginInfo(User user, @Va sormasToSormasOriginInfo.setWithSamples(options.isWithSamples()); sormasToSormasOriginInfo.setWithEventParticipants(options.isWithEventParticipants()); sormasToSormasOriginInfo.setWithImmunizations(options.isWithImmunizations()); + sormasToSormasOriginInfo.setWithSurveillanceReports(options.isWithSurveillanceReports()); sormasToSormasOriginInfo.setComment(options.getComment()); sormasToSormasOriginInfo.setPseudonymizedData(options.isPseudonymizeData()); @@ -132,6 +139,7 @@ public SormasToSormasOptionsDto createOptionsFormShareRequestInfo(ShareRequestIn options.setWithSamples(requestInfo.isWithSamples()); options.setWithEventParticipants(requestInfo.isWithEventParticipants()); options.setWithImmunizations(requestInfo.isWithImmunizations()); + options.setWithSurveillanceReports(requestInfo.isWithSurveillanceReports()); options.setComment(requestInfo.getComment()); options.setPseudonymizeData(requestInfo.isPseudonymizedPersonalData() || requestInfo.isPseudonymizedSensitiveData()); @@ -148,6 +156,7 @@ public SormasToSormasOptionsDto createOptionsFromOriginInfoDto(SormasToSormasOri options.setWithSamples(originInfo.isWithSamples()); options.setWithEventParticipants(originInfo.isWithEventParticipants()); options.setWithImmunizations(originInfo.isWithImmunizations()); + options.setWithSurveillanceReports(originInfo.isWithSurveillanceReports()); options.setComment(originInfo.getComment()); return options; @@ -172,4 +181,15 @@ public void clearIgnoredProperties(T dto) { } } } + + public SormasToSormasExternalMessageDto getExternalMessageDto(ExternalMessage externalMessage, ShareRequestInfo requestInfo) { + ExternalMessageDto externalMessageDto = externalMessageFacade.toDto(externalMessage); + externalMessageDto.setAssignee(null); + + if (!requestInfo.isWithSurveillanceReports()) { + externalMessageDto.setSurveillanceReport(null); + } + + return new SormasToSormasExternalMessageDto(externalMessageDto); + } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/ShareRequestInfo.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/ShareRequestInfo.java index 43750616b3b..1f89b82c202 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/ShareRequestInfo.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/ShareRequestInfo.java @@ -70,6 +70,8 @@ public class ShareRequestInfo extends AbstractDomainObject { private boolean withImmunizations; + private boolean withSurveillanceReports; + private boolean pseudonymizedPersonalData; private boolean pseudonymizedSensitiveData; @@ -156,6 +158,15 @@ public void setWithImmunizations(boolean withImmunizations) { this.withImmunizations = withImmunizations; } + @Column + public boolean isWithSurveillanceReports() { + return withSurveillanceReports; + } + + public void setWithSurveillanceReports(boolean withSurveillanceReports) { + this.withSurveillanceReports = withSurveillanceReports; + } + @Column public boolean isPseudonymizedPersonalData() { return pseudonymizedPersonalData; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfo.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfo.java index dd58889924f..87d657c02c3 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfo.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfo.java @@ -1,19 +1,16 @@ /* * SORMAS® - Surveillance Outbreak Response Management & Analysis System * Copyright © 2016-2022 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) - * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * 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 . + * along with this program. If not, see . */ package de.symeda.sormas.backend.sormastosormas.share.outgoing; @@ -31,6 +28,7 @@ import de.symeda.sormas.api.utils.FieldConstraints; import de.symeda.sormas.backend.caze.Case; +import de.symeda.sormas.backend.caze.surveillancereport.SurveillanceReport; import de.symeda.sormas.backend.common.AbstractDomainObject; import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.event.Event; @@ -51,6 +49,7 @@ public class SormasToSormasShareInfo extends AbstractDomainObject { public static final String EVENT = "event"; public static final String EVENT_PARTICIPANT = "eventParticipant"; public static final String IMMUNIZATION = "immunization"; + public static final String SURVEILLANCE_REPORT = "surveillanceReport"; public static final String ORGANIZATION_ID = "organizationId"; public static final String REQUESTS = "requests"; public static final String OWNERSHIP_HANDED_OVER = "ownershipHandedOver"; @@ -67,6 +66,8 @@ public class SormasToSormasShareInfo extends AbstractDomainObject { private Immunization immunization; + private SurveillanceReport surveillanceReport; + private String organizationId; private List requests; @@ -131,6 +132,15 @@ public void setImmunization(Immunization immunization) { this.immunization = immunization; } + @ManyToOne(fetch = FetchType.LAZY) + public SurveillanceReport getSurveillanceReport() { + return surveillanceReport; + } + + public void setSurveillanceReport(SurveillanceReport surveillanceReport) { + this.surveillanceReport = surveillanceReport; + } + @Column(length = FieldConstraints.CHARACTER_LIMIT_DEFAULT, nullable = false) public String getOrganizationId() { return organizationId; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfoFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfoFacadeEjb.java index bda83098e9e..36411e2a55f 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfoFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfoFacadeEjb.java @@ -120,6 +120,7 @@ public SormasToSormasShareInfoDto toDto(SormasToSormasShareInfo source) { target.setWithSamples(latestRequest.isWithSamples()); target.setWithEvenParticipants(latestRequest.isWithEventParticipants()); target.setWithImmunizations(latestRequest.isWithImmunizations()); + target.setWithSurveillanceReports(latestRequest.isWithSurveillanceReports()); target.setPseudonymizedPersonalData(latestRequest.isPseudonymizedPersonalData()); target.setPseudonymizedSensitiveData(latestRequest.isPseudonymizedSensitiveData()); target.setComment(latestRequest.getComment()); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfoService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfoService.java index 9a53ed3812a..4e52105a801 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfoService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/share/outgoing/SormasToSormasShareInfoService.java @@ -37,6 +37,7 @@ import de.symeda.sormas.api.sormastosormas.share.outgoing.SormasToSormasShareInfoCriteria; import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.caze.CaseFacadeEjb; +import de.symeda.sormas.backend.caze.surveillancereport.SurveillanceReport; import de.symeda.sormas.backend.common.AbstractDomainObject; import de.symeda.sormas.backend.common.AdoServiceWithUserFilterAndJurisdiction; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; @@ -114,6 +115,15 @@ public Predicate buildCriteriaFilter(SormasToSormasShareInfoCriteria criteria, C criteria.getImmunization().getUuid())); } + if (criteria.getSurveillanceReport() != null) { + filter = CriteriaBuilderHelper.and( + cb, + filter, + cb.equal( + from.join(SormasToSormasShareInfo.SURVEILLANCE_REPORT, JoinType.LEFT).get(SurveillanceReport.UUID), + criteria.getSurveillanceReport().getUuid())); + } + return filter; } @@ -192,6 +202,10 @@ public SormasToSormasShareInfo getByImmunizationAndOrganization(String immunizat return getByOrganization(SormasToSormasShareInfo.IMMUNIZATION, immunizationUuid, organizationId); } + public SormasToSormasShareInfo getBySurveillanceReportAndOrganization(String surveillanceUuid, String organizationId) { + return getByOrganization(SormasToSormasShareInfo.SURVEILLANCE_REPORT, surveillanceUuid, organizationId); + } + public SormasToSormasShareInfo getByOrganization(String associatedObjectField, String associatedObjectUuid, String organizationId) { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cq = cb.createQuery(SormasToSormasShareInfo.class); diff --git a/sormas-backend/src/main/resources/sql/sormas_schema.sql b/sormas-backend/src/main/resources/sql/sormas_schema.sql index fea9bca0898..3526b410235 100644 --- a/sormas-backend/src/main/resources/sql/sormas_schema.sql +++ b/sormas-backend/src/main/resources/sql/sormas_schema.sql @@ -12256,4 +12256,22 @@ INSERT INTO userroles_userrights (userrole_id, userright) SELECT id, 'TASK_ARCHI INSERT INTO schema_version (version_number, comment) VALUES (504, 'Add task archive user right #4060'); +-- 2022-12-08 S2S Surveillance Reports should be shareable (along with possibly attached External Messages) #10247 +ALTER TABLE sormastosormasorigininfo ADD COLUMN withsurveillancereports boolean DEFAULT false; +ALTER TABLE sormastosormasorigininfo_history ADD COLUMN withsurveillancereports boolean DEFAULT false; +ALTER TABLE sharerequestinfo ADD COLUMN withsurveillancereports boolean DEFAULT false; +ALTER TABLE sharerequestinfo_history ADD COLUMN withsurveillancereports boolean DEFAULT false; +ALTER TABLE sormastosormasshareinfo ADD COLUMN surveillancereport_id bigint; +ALTER TABLE sormastosormasshareinfo ADD CONSTRAINT fk_sormastosormasshareinfo_surveillancereport_id FOREIGN KEY (surveillancereport_id) REFERENCES surveillancereports (id) ON UPDATE NO ACTION ON DELETE NO ACTION; +ALTER TABLE sormastosormasshareinfo_history ADD COLUMN surveillancereport_id bigint; + +ALTER TABLE surveillancereports ADD COLUMN sormastosormasorigininfo_id bigint; +ALTER TABLE surveillancereports ADD CONSTRAINT fk_surveillancereports_sormastosormasorigininfo_id FOREIGN KEY (sormastosormasorigininfo_id) REFERENCES sormastosormasorigininfo (id) ON UPDATE NO ACTION ON DELETE NO ACTION; +ALTER TABLE surveillancereports_history ADD COLUMN sormastosormasorigininfo_id bigint; + +ALTER TABLE surveillancereports RENAME COLUMN creatinguser_id to reportinguser_id; +ALTER TABLE surveillancereports_history RENAME COLUMN creatinguser_id to reportinguser_id; + +INSERT INTO schema_version (version_number, comment) VALUES (505, 'S2S Surveillance Reports should be shareable (along with possibly attached External Messages) #10247'); + -- *** Insert new sql commands BEFORE this line. Remember to always consider _history tables. *** diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/AbstractBeanTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/AbstractBeanTest.java index 6ccd5ef3b96..190ea02aa40 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/AbstractBeanTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/AbstractBeanTest.java @@ -147,8 +147,8 @@ import de.symeda.sormas.backend.event.EventParticipantService; import de.symeda.sormas.backend.event.EventService; import de.symeda.sormas.backend.externaljournal.ExternalJournalService; -import de.symeda.sormas.backend.externalmessage.ExternalMessageFacadeEjb.ExternalMessageFacadeEjbLocal; import de.symeda.sormas.backend.externalmessage.ExternalMessageService; +import de.symeda.sormas.backend.externalmessage.ExternalMessageFacadeEjb.ExternalMessageFacadeEjbLocal; import de.symeda.sormas.backend.externalmessage.labmessage.SampleReportFacadeEjb; import de.symeda.sormas.backend.externalmessage.labmessage.SampleReportService; import de.symeda.sormas.backend.externalmessage.labmessage.TestReportFacadeEjb; @@ -213,6 +213,7 @@ import de.symeda.sormas.backend.sormastosormas.entities.immunization.SormasToSormasImmunizationDtoValidator; import de.symeda.sormas.backend.sormastosormas.entities.sample.ReceivedSampleProcessor; import de.symeda.sormas.backend.sormastosormas.entities.sample.SormasToSormasSampleDtoValidator; +import de.symeda.sormas.backend.sormastosormas.entities.surveillancereport.SormasToSormasSurveillanceReportDtoValidator; import de.symeda.sormas.backend.sormastosormas.origin.SormasToSormasOriginInfoFacadeEjb.SormasToSormasOriginInfoFacadeEjbLocal; import de.symeda.sormas.backend.sormastosormas.share.ShareDataBuilderHelper; import de.symeda.sormas.backend.sormastosormas.share.incoming.SormasToSormasShareRequestFacadeEJB.SormasToSormasShareRequestFacadeEJBLocal; @@ -969,6 +970,10 @@ public SormasToSormasExternalMessageDtoValidator getSormasToSormasLabMessageDtoV return getBean(SormasToSormasExternalMessageDtoValidator.class); } + public SormasToSormasSurveillanceReportDtoValidator getSormasToSormasSurveillanceReportDtoValidator() { + return getBean(SormasToSormasSurveillanceReportDtoValidator.class); + } + public DefaultEntitiesCreator getDefaultEntitiesCreator() { return getBean(DefaultEntitiesCreator.class); } 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 a53b3751dd2..90e2c3a6a27 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 @@ -1189,11 +1189,23 @@ public SurveillanceReportDto createSurveillanceReport( UserReferenceDto reportingUser, ReportingType reportingType, CaseReferenceDto caseReference) { + return createSurveillanceReport(reportingUser, reportingType, caseReference, null); + } + + public SurveillanceReportDto createSurveillanceReport( + UserReferenceDto reportingUser, + ReportingType reportingType, + CaseReferenceDto caseReference, + Consumer extraConfig) { SurveillanceReportDto surveillanceReport = SurveillanceReportDto.build(caseReference, reportingUser); surveillanceReport.setReportingType(reportingType); surveillanceReport.setReportDate(new Date()); - surveillanceReport = beanTest.getSurveillanceReportFacade().saveSurveillanceReport(surveillanceReport); + if (extraConfig != null) { + extraConfig.accept(surveillanceReport); + } + + surveillanceReport = beanTest.getSurveillanceReportFacade().save(surveillanceReport); return surveillanceReport; } diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/SurveillanceReportFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/SurveillanceReportFacadeEjbTest.java new file mode 100644 index 00000000000..6b58f8bce45 --- /dev/null +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/caze/SurveillanceReportFacadeEjbTest.java @@ -0,0 +1,69 @@ +/* + * SORMAS® - Surveillance Outbreak Response Management & Analysis System + * Copyright © 2016-2022 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.symeda.sormas.backend.caze; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Date; + +import org.junit.jupiter.api.Test; + +import de.symeda.sormas.api.caze.CaseDataDto; +import de.symeda.sormas.api.caze.surveillancereport.ReportingType; +import de.symeda.sormas.api.caze.surveillancereport.SurveillanceReportDto; +import de.symeda.sormas.api.user.DefaultUserRole; +import de.symeda.sormas.api.user.UserDto; +import de.symeda.sormas.backend.AbstractBeanTest; +import de.symeda.sormas.backend.TestDataCreator; + +public class SurveillanceReportFacadeEjbTest extends AbstractBeanTest { + + @Test + public void testSaveSurveillanceReport() { + TestDataCreator.RDCF rdcf = creator.createRDCF(); + UserDto user = creator.createUser(rdcf, creator.getUserRoleReference(DefaultUserRole.SURVEILLANCE_OFFICER)); + + CaseDataDto caze = creator.createCase(user.toReference(), creator.createPerson().toReference(), rdcf); + SurveillanceReportDto newReport = SurveillanceReportDto.build(caze.toReference(), user.toReference()); + newReport.setReportDate(new Date()); + newReport.setDateOfDiagnosis(new Date()); + newReport.setReportingType(ReportingType.LABORATORY); + newReport.setFacilityRegion(rdcf.region); + newReport.setFacilityDistrict(rdcf.district); + newReport.setFacility(rdcf.facility); + + SurveillanceReportDto savedReport = getSurveillanceReportFacade().save(newReport); + assertEquals(newReport.getCaze(), savedReport.getCaze()); + assertEquals(newReport.getReportingUser(), savedReport.getReportingUser()); + assertEquals(newReport.getReportDate(), savedReport.getReportDate()); + assertEquals(newReport.getDateOfDiagnosis(), savedReport.getDateOfDiagnosis()); + assertEquals(newReport.getReportingType(), savedReport.getReportingType()); + assertEquals(newReport.getFacilityRegion(), savedReport.getFacilityRegion()); + assertEquals(newReport.getFacilityDistrict(), savedReport.getFacilityDistrict()); + assertEquals(newReport.getFacility(), savedReport.getFacility()); + + SurveillanceReportDto reloadedReport = getSurveillanceReportFacade().getByUuid(savedReport.getUuid()); + assertEquals(newReport.getCaze(), reloadedReport.getCaze()); + assertEquals(newReport.getReportingUser(), reloadedReport.getReportingUser()); + assertEquals(newReport.getReportDate(), reloadedReport.getReportDate()); + assertEquals(newReport.getDateOfDiagnosis(), reloadedReport.getDateOfDiagnosis()); + assertEquals(newReport.getReportingType(), reloadedReport.getReportingType()); + assertEquals(newReport.getFacilityRegion(), reloadedReport.getFacilityRegion()); + assertEquals(newReport.getFacilityDistrict(), reloadedReport.getFacilityDistrict()); + assertEquals(newReport.getFacility(), reloadedReport.getFacility()); + + } +} diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/entities/SormasToSormasCaseFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/entities/SormasToSormasCaseFacadeEjbTest.java index 3179be8f102..863ac666956 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/entities/SormasToSormasCaseFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/entities/SormasToSormasCaseFacadeEjbTest.java @@ -43,6 +43,8 @@ import de.symeda.sormas.api.caze.CaseOrigin; import de.symeda.sormas.api.caze.CaseReferenceDto; import de.symeda.sormas.api.caze.porthealthinfo.PortHealthInfoDto; +import de.symeda.sormas.api.caze.surveillancereport.ReportingType; +import de.symeda.sormas.api.caze.surveillancereport.SurveillanceReportDto; import de.symeda.sormas.api.contact.ContactDto; import de.symeda.sormas.api.contact.ContactStatus; import de.symeda.sormas.api.contact.FollowUpStatus; @@ -51,6 +53,8 @@ import de.symeda.sormas.api.exposure.AnimalContactType; import de.symeda.sormas.api.exposure.ExposureDto; import de.symeda.sormas.api.exposure.ExposureType; +import de.symeda.sormas.api.externalmessage.ExternalMessageDto; +import de.symeda.sormas.api.externalmessage.ExternalMessageStatus; import de.symeda.sormas.api.immunization.ImmunizationDto; import de.symeda.sormas.api.infrastructure.facility.FacilityDto; import de.symeda.sormas.api.infrastructure.facility.FacilityReferenceDto; @@ -74,7 +78,9 @@ import de.symeda.sormas.api.sormastosormas.entities.SyncDataDto; import de.symeda.sormas.api.sormastosormas.entities.caze.SormasToSormasCaseDto; import de.symeda.sormas.api.sormastosormas.entities.contact.SormasToSormasContactDto; +import de.symeda.sormas.api.sormastosormas.entities.externalmessage.SormasToSormasExternalMessageDto; import de.symeda.sormas.api.sormastosormas.entities.sample.SormasToSormasSampleDto; +import de.symeda.sormas.api.sormastosormas.entities.surveillancereport.SormasToSormasSurveillanceReportDto; import de.symeda.sormas.api.sormastosormas.share.incoming.ShareRequestDataType; import de.symeda.sormas.api.sormastosormas.share.incoming.ShareRequestStatus; import de.symeda.sormas.api.sormastosormas.share.incoming.SormasToSormasShareRequestDto; @@ -89,6 +95,7 @@ import de.symeda.sormas.api.utils.YesNoUnknown; import de.symeda.sormas.backend.MockProducer; import de.symeda.sormas.backend.TestDataCreator; +import de.symeda.sormas.backend.externalmessage.ExternalMessage; import de.symeda.sormas.backend.sormastosormas.SormasToSormasTest; import de.symeda.sormas.backend.sormastosormas.share.ShareRequestAcceptData; import de.symeda.sormas.backend.sormastosormas.share.outgoing.ShareRequestInfo; @@ -1237,6 +1244,247 @@ public void testSyncNotUpdateOwnedPerson() throws SormasToSormasException, Sorma assertThat(syncedPerson.getBirthName(), is(nullValue())); } + @Test + public void testShareWithSurveillanceReports() throws SormasToSormasException { + UserDto user = creator.createUser(rdcf, creator.getUserRoleReference(DefaultUserRole.SURVEILLANCE_OFFICER)); + + PersonDto person = creator.createPerson(); + UserReferenceDto officer = user.toReference(); + CaseDataDto caze = creator.createCase(officer, rdcf, dto -> { + dto.setPerson(person.toReference()); + dto.setSurveillanceOfficer(officer); + dto.setClassificationUser(officer); + }); + + SurveillanceReportDto surveillanceReport = creator.createSurveillanceReport(officer, ReportingType.LABORATORY, caze.toReference(), (r) -> { + r.setReportDate(new Date()); + r.setFacilityRegion(rdcf.region); + r.setFacilityDistrict(rdcf.district); + r.setFacility(rdcf.facility); + r.setNotificationDetails("Test lab report notification"); + }); + + SurveillanceReportDto surveillanceReport2 = creator.createSurveillanceReport(officer, ReportingType.DOCTOR, caze.toReference(), (r) -> { + r.setReportDate(new Date()); + r.setFacilityRegion(rdcf.region); + r.setFacilityDistrict(rdcf.district); + r.setFacility(rdcf.facility); + r.setNotificationDetails("Test doctor report notification"); + }); + + SormasToSormasOptionsDto options = new SormasToSormasOptionsDto(); + options.setOrganization(new SormasServerDescriptor(SECOND_SERVER_ID)); + options.setComment("Test comment"); + options.setWithSurveillanceReports(true); + + Mockito + .when( + MockProducer.getSormasToSormasClient() + .post(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), ArgumentMatchers.any(), ArgumentMatchers.any())) + .thenAnswer(invocation -> { + + assertThat(invocation.getArgument(0, String.class), is(SECOND_SERVER_ID)); + assertThat(invocation.getArgument(1, String.class), is("/sormasToSormas/cases")); + + SormasToSormasDto postBody = invocation.getArgument(2, SormasToSormasDto.class); + + assertThat(postBody.getSurveillanceReports().size(), is(2)); + SormasToSormasSurveillanceReportDto sharedSurveillanceReport = postBody.getSurveillanceReports() + .stream() + .filter(r -> r.getEntity().getUuid().equals(surveillanceReport.getUuid())) + .findFirst() + .get(); + assertThat(sharedSurveillanceReport.getEntity().getReportDate().compareTo(surveillanceReport.getReportDate()), is(0)); // use compareTo because getReportDate() returns Timestamp object due to SurveillanceReport.java using TemporalType.Timestamp + assertThat(sharedSurveillanceReport.getEntity().getReportingType(), is(surveillanceReport.getReportingType())); + assertThat(sharedSurveillanceReport.getEntity().getFacilityRegion(), is(surveillanceReport.getFacilityRegion())); + assertThat(sharedSurveillanceReport.getEntity().getFacilityDistrict(), is(surveillanceReport.getFacilityDistrict())); + assertThat(sharedSurveillanceReport.getEntity().getFacility(), is(surveillanceReport.getFacility())); + assertThat(sharedSurveillanceReport.getEntity().getNotificationDetails(), is(surveillanceReport.getNotificationDetails())); + + return encryptShareData(new ShareRequestAcceptData(null, null)); + }); + + getSormasToSormasCaseFacade().share(Collections.singletonList(caze.getUuid()), options); + + List surveillanceReportShareInfoList = getSormasToSormasShareInfoFacade() + .getIndexList(new SormasToSormasShareInfoCriteria().surveillanceReport(surveillanceReport.toReference()), 0, 100); + + SormasToSormasShareInfoDto contactShareInfo = surveillanceReportShareInfoList.get(0); + assertThat(contactShareInfo.getTargetDescriptor().getId(), is(SECOND_SERVER_ID)); + assertThat(contactShareInfo.getSender().getCaption(), is("ad MIN")); + assertThat(contactShareInfo.getComment(), is("Test comment")); + + List surveillanceReport2ShareInfoList = getSormasToSormasShareInfoFacade() + .getIndexList(new SormasToSormasShareInfoCriteria().surveillanceReport(surveillanceReport2.toReference()), 0, 100); + + assertThat(surveillanceReport2ShareInfoList, hasSize(1)); + } + + @Test + public void testSharePseudonymizedWithSurveillanceReport() throws SormasToSormasException { + UserDto user = creator.createUser(rdcf, creator.getUserRoleReference(DefaultUserRole.SURVEILLANCE_OFFICER)); + + PersonDto person = creator.createPerson(); + UserReferenceDto officer = user.toReference(); + CaseDataDto caze = creator.createCase(officer, rdcf, dto -> { + dto.setPerson(person.toReference()); + dto.setSurveillanceOfficer(officer); + dto.setClassificationUser(officer); + }); + + SurveillanceReportDto surveillanceReport = creator.createSurveillanceReport(officer, ReportingType.LABORATORY, caze.toReference(), (r) -> { + r.setReportDate(new Date()); + r.setFacilityRegion(rdcf.region); + r.setFacilityDistrict(rdcf.district); + r.setFacility(rdcf.facility); + r.setFacilityDetails("Test facility details"); + r.setNotificationDetails("Test lab report notification"); + }); + + SormasToSormasOptionsDto options = new SormasToSormasOptionsDto(); + options.setOrganization(new SormasServerDescriptor(SECOND_SERVER_ID)); + options.setComment("Test comment"); + options.setWithSurveillanceReports(true); + options.setPseudonymizeData(true); + + Mockito + .when( + MockProducer.getSormasToSormasClient() + .post(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), ArgumentMatchers.any(), ArgumentMatchers.any())) + .thenAnswer(invocation -> { + + assertThat(invocation.getArgument(0, String.class), is(SECOND_SERVER_ID)); + assertThat(invocation.getArgument(1, String.class), is("/sormasToSormas/cases")); + + SormasToSormasDto postBody = invocation.getArgument(2, SormasToSormasDto.class); + + SormasToSormasSurveillanceReportDto sharedSurveillanceReport = postBody.getSurveillanceReports().get(0); + assertThat(sharedSurveillanceReport.getEntity().getFacility(), is(surveillanceReport.getFacility())); + assertThat(sharedSurveillanceReport.getEntity().getFacilityDetails(), is("")); + assertThat(sharedSurveillanceReport.getEntity().getNotificationDetails(), is("")); + + return encryptShareData(new ShareRequestAcceptData(null, null)); + }); + + getSormasToSormasCaseFacade().share(Collections.singletonList(caze.getUuid()), options); + } + + @Test + public void testShareWithSurveillanceReportAndExternalMessage() throws SormasToSormasException { + UserDto user = creator.createUser(rdcf, creator.getUserRoleReference(DefaultUserRole.SURVEILLANCE_OFFICER)); + + PersonDto person = creator.createPerson(); + UserReferenceDto officer = user.toReference(); + CaseDataDto caze = creator.createCase(officer, rdcf, dto -> { + dto.setPerson(person.toReference()); + dto.setSurveillanceOfficer(officer); + dto.setClassificationUser(officer); + }); + + SurveillanceReportDto report = creator.createSurveillanceReport(officer, ReportingType.LABORATORY, caze.toReference(), (r) -> { + r.setReportDate(new Date()); + r.setFacilityRegion(rdcf.region); + r.setFacilityDistrict(rdcf.district); + r.setFacility(rdcf.facility); + r.setNotificationDetails("Test lab report notification"); + }); + + ExternalMessageDto externalMessage = creator.createExternalMessage(m -> { + m.setStatus(ExternalMessageStatus.PROCESSED); + m.setSurveillanceReport(report.toReference()); + }); + + SormasToSormasOptionsDto options = new SormasToSormasOptionsDto(); + options.setOrganization(new SormasServerDescriptor(SECOND_SERVER_ID)); + options.setComment("Test comment"); + options.setWithSurveillanceReports(true); + options.setHandOverOwnership(true); + + Mockito + .when( + MockProducer.getSormasToSormasClient() + .post(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), ArgumentMatchers.any(), ArgumentMatchers.any())) + .thenAnswer(invocation -> { + + assertThat(invocation.getArgument(0, String.class), is(SECOND_SERVER_ID)); + assertThat(invocation.getArgument(1, String.class), is("/sormasToSormas/cases")); + + SormasToSormasDto postBody = invocation.getArgument(2, SormasToSormasDto.class); + + SormasToSormasExternalMessageDto sharedExternalMessage = postBody.getSurveillanceReports().get(0).getExternalMessage(); + assertThat(sharedExternalMessage.getEntity().getUuid(), is(externalMessage.getUuid())); + assertThat(sharedExternalMessage.getEntity().getStatus(), is(externalMessage.getStatus())); + assertThat(sharedExternalMessage.getEntity().getSurveillanceReport(), is(report.toReference())); + + return encryptShareData(new ShareRequestAcceptData(null, null)); + }); + + getSormasToSormasCaseFacade().share(Collections.singletonList(caze.getUuid()), options); + + assertThat(getExternalMessageFacade().getByUuid(externalMessage.getUuid()).getStatus(), is(ExternalMessageStatus.FORWARDED)); + } + + @Test + public void testSaveSharedWithSurveillanceReports() throws SormasToSormasException, SormasToSormasValidationException { + PersonDto person = createPersonDto(rdcf); + CaseDataDto caze = createCaseDto(rdcf, person); + SurveillanceReportDto report = SurveillanceReportDto.build(caze.toReference(), null); + report.setReportDate(new Date()); + report.setReportingType(ReportingType.LABORATORY); + report.setFacilityRegion(rdcf.region); + report.setFacilityDistrict(rdcf.district); + report.setFacility(rdcf.facility); + report.setNotificationDetails("Test notification details"); + + SormasToSormasDto shareData = new SormasToSormasDto(); + shareData.setOriginInfo(createSormasToSormasOriginInfoDto(DEFAULT_SERVER_ID, false)); + shareData.setCases(Collections.singletonList(new SormasToSormasCaseDto(person, caze))); + shareData.setSurveillanceReports(Collections.singletonList(new SormasToSormasSurveillanceReportDto(report, null))); + + SormasToSormasEncryptedDataDto encryptedData = encryptShareData(shareData); + getSormasToSormasCaseFacade().saveSharedEntities(encryptedData); + + CaseDataDto savedCase = getCaseFacade().getCaseDataByUuid(caze.getUuid()); + SurveillanceReportDto savedReport = getSurveillanceReportFacade().getByUuid(report.getUuid()); + + assertThat(savedReport, is(notNullValue())); + assertThat(savedReport.getReportDate().compareTo(report.getReportDate()), is(0)); + assertThat(savedReport.getReportingType(), is(report.getReportingType())); + assertThat(savedReport.getFacilityRegion(), is(report.getFacilityRegion())); + assertThat(savedReport.getFacilityDistrict(), is(report.getFacilityDistrict())); + assertThat(savedReport.getFacility(), is(report.getFacility())); + assertThat(savedReport.getNotificationDetails(), is(report.getNotificationDetails())); + + assertThat(savedCase.getSormasToSormasOriginInfo().getUuid(), is(savedReport.getSormasToSormasOriginInfo().getUuid())); + } + + @Test + public void testSaveSharedCaseWithSurveillanceReportAndExternalMessage() throws SormasToSormasException, SormasToSormasValidationException { + PersonDto person = createPersonDto(rdcf); + CaseDataDto caze = createCaseDto(rdcf, person); + + SurveillanceReportDto report = SurveillanceReportDto.build(caze.toReference(), null); + report.setReportDate(new Date()); + report.setReportingType(ReportingType.LABORATORY); + + ExternalMessageDto externalMessage = ExternalMessageDto.build(); + externalMessage.setSurveillanceReport(report.toReference()); + externalMessage.setStatus(ExternalMessageStatus.PROCESSED); + + SormasToSormasDto shareData = new SormasToSormasDto(); + shareData.setOriginInfo(createSormasToSormasOriginInfoDto(DEFAULT_SERVER_ID, false)); + shareData.setCases(Collections.singletonList(new SormasToSormasCaseDto(person, caze))); + shareData.setSurveillanceReports( + Collections.singletonList(new SormasToSormasSurveillanceReportDto(report, new SormasToSormasExternalMessageDto(externalMessage)))); + + SormasToSormasEncryptedDataDto encryptedData = encryptShareData(shareData); + getSormasToSormasCaseFacade().saveSharedEntities(encryptedData); + + ExternalMessage savedExternalMessage = getSurveillanceReportService().getByUuid(report.getUuid()).getExternalMessage(); + assertThat(savedExternalMessage.getUuid(), is(externalMessage.getUuid())); + assertThat(savedExternalMessage.getStatus(), is(externalMessage.getStatus())); + } + private ContactDto createRemoteContactDto(TestDataCreator.RDCF remoteRdcf, CaseDataDto caze) { ContactDto contact = ContactDto.build(caze); contact.setRegion(remoteRdcf.region); diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/validation/InfraValidationSoundnessTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/validation/InfraValidationSoundnessTest.java index 7eebffd7225..4d349d0c5ba 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/validation/InfraValidationSoundnessTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/sormastosormas/validation/InfraValidationSoundnessTest.java @@ -45,6 +45,7 @@ import de.symeda.sormas.api.sormastosormas.entities.externalmessage.SormasToSormasExternalMessageDto; import de.symeda.sormas.api.sormastosormas.entities.immunization.SormasToSormasImmunizationDto; import de.symeda.sormas.api.sormastosormas.entities.sample.SormasToSormasSampleDto; +import de.symeda.sormas.api.sormastosormas.entities.surveillancereport.SormasToSormasSurveillanceReportDto; import de.symeda.sormas.api.sormastosormas.share.incoming.PreviewNotImplementedDto; import de.symeda.sormas.api.sormastosormas.share.incoming.SormasToSormasCasePreview; import de.symeda.sormas.api.sormastosormas.share.incoming.SormasToSormasContactPreview; @@ -70,6 +71,7 @@ import de.symeda.sormas.backend.sormastosormas.entities.eventparticipant.SormasToSormasEventParticipantDtoValidator; import de.symeda.sormas.backend.sormastosormas.entities.externalmessage.SormasToSormasExternalMessageDtoValidator; import de.symeda.sormas.backend.sormastosormas.entities.immunization.SormasToSormasImmunizationDtoValidator; +import de.symeda.sormas.backend.sormastosormas.entities.surveillancereport.SormasToSormasSurveillanceReportDtoValidator; public abstract class InfraValidationSoundnessTest extends AbstractBeanTest { @@ -82,6 +84,7 @@ public abstract class InfraValidationSoundnessTest extends AbstractBeanTest { protected SormasToSormasEventParticipantDtoValidator eventParticipantDtoValidator; protected SormasToSormasImmunizationDtoValidator immunizationDtoValidator; protected SormasToSormasExternalMessageDtoValidator labMessageDtoValidator; + protected SormasToSormasSurveillanceReportDtoValidator surveillanceReportDtoValidator; @Override public void init() { @@ -92,6 +95,7 @@ public void init() { eventParticipantDtoValidator = getSormasToSormasEventParticipantDtoValidator(); immunizationDtoValidator = getSormasToSormasImmunizationDtoValidator(); labMessageDtoValidator = getSormasToSormasLabMessageDtoValidator(); + surveillanceReportDtoValidator = getSormasToSormasSurveillanceReportDtoValidator(); } /** @@ -779,4 +783,27 @@ public SamplePreviewRootNode(PreviewNotImplementedDto dtoUnderTest) { assertValidationDto(sampleDto, rootNode, getSormasToSormasSampleDtoValidator()); } + + @Test + public void testSurveillanceReportValidation() + throws NoSuchFieldException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { + class SurveillanceReportDtoRootNode extends DtoRootNode { + + public SurveillanceReportDtoRootNode(SormasToSormasSurveillanceReportDto dtoUnderTest) { + super(dtoUnderTest); + } + } + + class SurveillanceReportPreviewRootNode extends DtoRootNode { + + // todo add test once preview is available for this entity + public SurveillanceReportPreviewRootNode(PreviewNotImplementedDto dtoUnderTest) { + super(dtoUnderTest); + } + } + before(); + SormasToSormasSurveillanceReportDto surveillanceReportDto = new SormasToSormasSurveillanceReportDto(); + SurveillanceReportDtoRootNode rootNode = new SurveillanceReportDtoRootNode(surveillanceReportDto); + assertValidationDto(surveillanceReportDto, rootNode, surveillanceReportDtoValidator); + } } diff --git a/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/SurveillanceReportResource.java b/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/SurveillanceReportResource.java index 02d02dc9aad..672157ce3d8 100644 --- a/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/SurveillanceReportResource.java +++ b/sormas-rest/src/main/java/de/symeda/sormas/rest/resources/SurveillanceReportResource.java @@ -29,6 +29,6 @@ public List getByCaseUuids(List uuids) { @POST @Path("/push") public List postCaseReports(@Valid List dtos) { - return savePushedDto(dtos, FacadeProvider.getSurveillanceReportFacade()::saveSurveillanceReport); + return savePushedDto(dtos, FacadeProvider.getSurveillanceReportFacade()::save); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/surveillancereport/SurveillanceReportController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/surveillancereport/SurveillanceReportController.java index 310a5ff3d79..0557f434f43 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/surveillancereport/SurveillanceReportController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/surveillancereport/SurveillanceReportController.java @@ -57,12 +57,12 @@ private void openEditWindow(SurveillanceReportDto report, String titleTag, boole if (isEditAllowed) { editView.addCommitListener(() -> { - FacadeProvider.getSurveillanceReportFacade().saveSurveillanceReport(surveillanceReportForm.getValue()); + FacadeProvider.getSurveillanceReportFacade().save(surveillanceReportForm.getValue()); callback.run(); }); if (canDelete) { editView.addDeleteListener(() -> { - FacadeProvider.getSurveillanceReportFacade().deleteSurveillanceReport(report.getUuid()); + FacadeProvider.getSurveillanceReportFacade().delete(report.getUuid()); window.close(); callback.run(); }, I18nProperties.getCaption(SurveillanceReportDto.I18N_PREFIX)); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/surveillancereport/SurveillanceReportForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/surveillancereport/SurveillanceReportForm.java index 8024c5235e8..2f68d12f3bb 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/surveillancereport/SurveillanceReportForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/surveillancereport/SurveillanceReportForm.java @@ -45,7 +45,7 @@ public class SurveillanceReportForm extends AbstractEditForm reports = FacadeProvider.getSurveillanceReportFacade().getIndexList(criteria, 0, maxDisplayedEntries * 20); + List reports = FacadeProvider.getSurveillanceReportFacade().getIndexList(criteria, 0, maxDisplayedEntries * 20, null); setEntries(reports); if (!reports.isEmpty()) { @@ -84,15 +84,18 @@ protected void drawDisplayedEntries() { SurveillanceReportDto report = displayedEntries.get(i); SurveillanceReportListEntry listEntry = new SurveillanceReportListEntry(report); - boolean editState = UserProvider.getCurrent().hasUserRight(UserRight.CASE_EDIT) && isEditAllowed; + boolean isEditable = UserProvider.getCurrent().hasUserRight(UserRight.CASE_EDIT) + && isEditAllowed + && !report.isOwnershipHandedOver() + && (report.getSormasToSormasOriginInfo() == null || report.getSormasToSormasOriginInfo().isOwnershipHandedOver()); listEntry.addActionButton( report.getUuid(), (Button.ClickListener) event -> ControllerProvider.getSurveillanceReportController() - .editSurveillanceReport(listEntry.getReport(), this::reload, editState), - editState); + .editSurveillanceReport(listEntry.getReport(), this::reload, isEditable), + isEditable); - listEntry.setEnabled(editState); + listEntry.setEnabled(isEditable); if (UserProvider.getCurrent().getUserRights().contains(UserRight.EXTERNAL_MESSAGE_VIEW)) { addViewExternalMessageButton(listEntry); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageController.java index 12db7dc39a2..6cea86c7b9d 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/ExternalMessageController.java @@ -148,7 +148,7 @@ public void processLabMessage(String labMessageUuid) { SurveillanceReportDto surveillanceReport = null; if (caseReference != null) { surveillanceReport = createSurveillanceReport(labMessage, caseReference); - FacadeProvider.getSurveillanceReportFacade().saveSurveillanceReport(surveillanceReport); + FacadeProvider.getSurveillanceReportFacade().save(surveillanceReport); } markExternalMessageAsProcessed(labMessage, result.getData().getRelatedSampleReportsWithSamples(), surveillanceReport); SormasUI.get().getNavigator().navigateTo(ExternalMessagesView.VIEW_NAME); @@ -179,7 +179,7 @@ public void processPhysiciansReport(String uuid) { if (status == ProcessingResultStatus.DONE) { CaseReferenceDto caseReferenceDto = result.getData().toReference(); SurveillanceReportDto surveillanceReport = createSurveillanceReport(labMessage, caseReferenceDto); - FacadeProvider.getSurveillanceReportFacade().saveSurveillanceReport(surveillanceReport); + FacadeProvider.getSurveillanceReportFacade().save(surveillanceReport); markExternalMessageAsProcessed(labMessage, surveillanceReport); SormasUI.get().getNavigator().navigateTo(ExternalMessagesView.VIEW_NAME); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/SormasToSormasOptionsForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/SormasToSormasOptionsForm.java index 481b5d2d0c3..59e03059f85 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/SormasToSormasOptionsForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/SormasToSormasOptionsForm.java @@ -82,6 +82,8 @@ public class SormasToSormasOptionsForm extends AbstractEditForm availableCustomOptions; @@ -130,7 +133,8 @@ public static SormasToSormasOptionsForm forCase(CaseDataDto caze, List { if (form.allowedCustomOptions.contains(SormasToSormasOptionsDto.WITH_SAMPLES)) { @@ -164,6 +168,22 @@ public static SormasToSormasOptionsForm forCase(CaseDataDto caze, List Date: Mon, 9 Jan 2023 10:02:07 +0100 Subject: [PATCH 077/166] New Crowdin updates (#11297) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * New translations strings.properties (Swahili) * New translations strings.properties (Nepali) * New translations strings.properties (French, Switzerland) * New translations strings.properties (Italian, Switzerland) * New translations strings.properties (Dari) * New translations strings.properties (Pashto) * New translations strings.properties (Spanish, Cuba) * New translations strings.properties (English, Afghanistan) * New translations strings.properties (English, Nigeria) * New translations strings.properties (English, Ghana) * New translations enum.properties (Romanian) * New translations enum.properties (Spanish) * New translations enum.properties (Arabic) * New translations enum.properties (Czech) * New translations enum.properties (German) * New translations enum.properties (Finnish) * New translations enum.properties (Italian) * New translations enum.properties (Japanese) * New translations enum.properties (Dutch) * New translations enum.properties (Norwegian) * New translations enum.properties (Polish) * New translations enum.properties (Portuguese) * New translations enum.properties (Russian) * New translations enum.properties (Swedish) * New translations enum.properties (Turkish) * New translations enum.properties (Ukrainian) * New translations enum.properties (Chinese Simplified) * New translations enum.properties (Urdu (Pakistan)) * New translations enum.properties (Spanish, Ecuador) * New translations enum.properties (Croatian) * New translations enum.properties (Hindi) * New translations enum.properties (Filipino) * New translations enum.properties (Fijian) * New translations enum.properties (Swahili) * New translations enum.properties (German, Switzerland) * New translations enum.properties (Nepali) * New translations enum.properties (French, Switzerland) * New translations enum.properties (Italian, Switzerland) * New translations enum.properties (Dari) * New translations enum.properties (Pashto) * New translations enum.properties (Spanish, Cuba) * New translations enum.properties (English, Afghanistan) * New translations enum.properties (English, Nigeria) * New translations enum.properties (English, Ghana) * New translations enum.properties (French) * New translations captions.properties (French) * New translations strings.properties (Spanish, Cuba) * New translations enum.properties (Spanish, Cuba) * New translations captions.properties (Urdu (Pakistan)) * New translations strings.properties (Czech) * New translations strings.properties (Urdu (Pakistan)) * New translations enum.properties (Czech) * New translations enum.properties (Urdu (Pakistan)) * New translations descriptions.properties (Urdu (Pakistan)) * New translations validations.properties (Urdu (Pakistan)) * New translations enum.properties (French) * New translations enum.properties (Romanian) * New translations enum.properties (Spanish) * New translations enum.properties (Arabic) * New translations enum.properties (Czech) * New translations enum.properties (German) * New translations enum.properties (Finnish) * New translations enum.properties (Italian) * New translations enum.properties (Japanese) * New translations enum.properties (Dutch) * New translations enum.properties (Norwegian) * New translations enum.properties (Polish) * New translations enum.properties (Portuguese) * New translations enum.properties (Russian) * New translations enum.properties (Swedish) * New translations enum.properties (Turkish) * New translations enum.properties (Ukrainian) * New translations enum.properties (Chinese Simplified) * New translations enum.properties (Urdu (Pakistan)) * New translations enum.properties (Spanish, Ecuador) * New translations enum.properties (Croatian) * New translations enum.properties (Hindi) * New translations enum.properties (Filipino) * New translations enum.properties (Fijian) * New translations enum.properties (Swahili) * New translations enum.properties (German, Switzerland) * New translations enum.properties (Nepali) * New translations enum.properties (French, Switzerland) * New translations enum.properties (Italian, Switzerland) * New translations enum.properties (Dari) * New translations enum.properties (Pashto) * New translations enum.properties (Spanish, Cuba) * New translations enum.properties (English, Afghanistan) * New translations enum.properties (English, Nigeria) * New translations enum.properties (English, Ghana) * New translations enum.properties (Spanish, Cuba) * New translations strings.properties (German, Switzerland) * New translations strings.properties (Romanian) * New translations strings.properties (French) * New translations strings.properties (Spanish) * New translations strings.properties (Arabic) * New translations strings.properties (Czech) * New translations strings.properties (German) * New translations strings.properties (Finnish) * New translations strings.properties (Italian) * New translations strings.properties (Japanese) * New translations strings.properties (Dutch) * New translations strings.properties (Norwegian) * New translations strings.properties (Polish) * New translations strings.properties (Portuguese) * New translations strings.properties (Russian) * New translations strings.properties (Swedish) * New translations strings.properties (Turkish) * New translations strings.properties (Ukrainian) * New translations strings.properties (Chinese Simplified) * New translations strings.properties (Urdu (Pakistan)) * New translations strings.properties (Spanish, Ecuador) * New translations strings.properties (Croatian) * New translations strings.properties (Hindi) * New translations strings.properties (Filipino) * New translations strings.properties (Fijian) * New translations strings.properties (Swahili) * New translations strings.properties (Nepali) * New translations strings.properties (French, Switzerland) * New translations strings.properties (Italian, Switzerland) * New translations strings.properties (Dari) * New translations strings.properties (Pashto) * New translations strings.properties (Spanish, Cuba) * New translations strings.properties (English, Afghanistan) * New translations strings.properties (English, Nigeria) * New translations strings.properties (English, Ghana) * New translations strings.properties (German, Switzerland) * New translations strings.properties (Romanian) * New translations strings.properties (French) * New translations strings.properties (Spanish) * New translations strings.properties (Arabic) * New translations strings.properties (Czech) * New translations strings.properties (German) * New translations strings.properties (Finnish) * New translations strings.properties (Italian) * New translations strings.properties (Japanese) * New translations strings.properties (Dutch) * New translations strings.properties (Norwegian) * New translations strings.properties (Polish) * New translations strings.properties (Portuguese) * New translations strings.properties (Russian) * New translations strings.properties (Swedish) * New translations strings.properties (Turkish) * New translations strings.properties (Ukrainian) * New translations strings.properties (Chinese Simplified) * New translations strings.properties (Urdu (Pakistan)) * New translations strings.properties (Spanish, Ecuador) * New translations strings.properties (Croatian) * New translations strings.properties (Hindi) * New translations strings.properties (Filipino) * New translations strings.properties (Fijian) * New translations strings.properties (Swahili) * New translations strings.properties (Nepali) * New translations strings.properties (French, Switzerland) * New translations strings.properties (Italian, Switzerland) * New translations strings.properties (Dari) * New translations strings.properties (Pashto) * New translations strings.properties (Spanish, Cuba) * New translations strings.properties (English, Afghanistan) * New translations strings.properties (English, Nigeria) * New translations strings.properties (English, Ghana) * New translations strings.properties (German, Switzerland) * New translations enum.properties (French) * New translations strings.properties (Czech) * New translations strings.properties (German) * New translations strings.properties (Urdu (Pakistan)) * New translations strings.properties (Spanish, Cuba) * New translations enum.properties (German) * New translations enum.properties (Urdu (Pakistan)) * New translations enum.properties (German, Switzerland) * New translations enum.properties (French) * New translations strings.properties (French) * New translations strings.properties (German, Switzerland) * New translations strings.properties (Romanian) * New translations strings.properties (French) * New translations strings.properties (Spanish) * New translations strings.properties (Arabic) * New translations strings.properties (Czech) * New translations strings.properties (German) * New translations strings.properties (Finnish) * New translations strings.properties (Italian) * New translations strings.properties (Japanese) * New translations strings.properties (Dutch) * New translations strings.properties (Norwegian) * New translations strings.properties (Polish) * New translations strings.properties (Portuguese) * New translations strings.properties (Russian) * New translations strings.properties (Swedish) * New translations strings.properties (Turkish) * New translations strings.properties (Ukrainian) * New translations strings.properties (Chinese Simplified) * New translations strings.properties (Urdu (Pakistan)) * New translations strings.properties (Spanish, Ecuador) * New translations strings.properties (Croatian) * New translations strings.properties (Hindi) * New translations strings.properties (Filipino) * New translations strings.properties (Fijian) * New translations strings.properties (Swahili) * New translations strings.properties (Nepali) * New translations strings.properties (French, Switzerland) * New translations strings.properties (Italian, Switzerland) * New translations strings.properties (Dari) * New translations strings.properties (Pashto) * New translations strings.properties (Spanish, Cuba) * New translations strings.properties (English, Afghanistan) * New translations strings.properties (English, Nigeria) * New translations strings.properties (English, Ghana) * New translations strings.properties (German) * New translations strings.properties (Urdu (Pakistan)) * New translations strings.properties (Spanish, Cuba) * New translations strings.properties (German, Switzerland) * New translations captions.properties (Romanian) * New translations captions.properties (French) * New translations captions.properties (Spanish) * New translations captions.properties (Arabic) * New translations captions.properties (Czech) * New translations captions.properties (German) * New translations captions.properties (Finnish) * New translations captions.properties (Italian) * New translations captions.properties (Japanese) * New translations captions.properties (Dutch) * New translations captions.properties (Norwegian) * New translations captions.properties (Polish) * New translations captions.properties (Portuguese) * New translations captions.properties (Russian) * New translations captions.properties (Swedish) * New translations captions.properties (Turkish) * New translations captions.properties (Ukrainian) * New translations captions.properties (Chinese Simplified) * New translations captions.properties (Urdu (Pakistan)) * New translations captions.properties (Spanish, Ecuador) * New translations captions.properties (Croatian) * New translations captions.properties (Hindi) * New translations captions.properties (Filipino) * New translations captions.properties (Fijian) * New translations captions.properties (Swahili) * New translations captions.properties (German, Switzerland) * New translations captions.properties (Nepali) * New translations captions.properties (French, Switzerland) * New translations captions.properties (Italian, Switzerland) * New translations captions.properties (Dari) * New translations captions.properties (Pashto) * New translations captions.properties (Spanish, Cuba) * New translations captions.properties (English, Afghanistan) * New translations captions.properties (English, Nigeria) * New translations captions.properties (English, Ghana) Co-authored-by: Maté Strysewske Co-authored-by: StefanKock --- .../main/resources/captions_ar-SA.properties | 24 ++++++++++++++----- .../main/resources/captions_cs-CZ.properties | 24 ++++++++++++++----- .../main/resources/captions_de-CH.properties | 24 ++++++++++++++----- .../main/resources/captions_de-DE.properties | 24 ++++++++++++++----- .../main/resources/captions_en-AF.properties | 24 ++++++++++++++----- .../main/resources/captions_en-GH.properties | 24 ++++++++++++++----- .../main/resources/captions_en-NG.properties | 24 ++++++++++++++----- .../main/resources/captions_es-CU.properties | 24 ++++++++++++++----- .../main/resources/captions_es-EC.properties | 24 ++++++++++++++----- .../main/resources/captions_es-ES.properties | 24 ++++++++++++++----- .../main/resources/captions_fa-AF.properties | 24 ++++++++++++++----- .../main/resources/captions_fi-FI.properties | 24 ++++++++++++++----- .../main/resources/captions_fil-PH.properties | 24 ++++++++++++++----- .../main/resources/captions_fj-FJ.properties | 24 ++++++++++++++----- .../main/resources/captions_fr-CH.properties | 24 ++++++++++++++----- .../main/resources/captions_fr-FR.properties | 24 ++++++++++++++----- .../main/resources/captions_hi-IN.properties | 24 ++++++++++++++----- .../main/resources/captions_hr-HR.properties | 24 ++++++++++++++----- .../main/resources/captions_it-CH.properties | 24 ++++++++++++++----- .../main/resources/captions_it-IT.properties | 24 ++++++++++++++----- .../main/resources/captions_ja-JP.properties | 24 ++++++++++++++----- .../main/resources/captions_ne-NP.properties | 24 ++++++++++++++----- .../main/resources/captions_nl-NL.properties | 24 ++++++++++++++----- .../main/resources/captions_no-NO.properties | 24 ++++++++++++++----- .../main/resources/captions_pl-PL.properties | 24 ++++++++++++++----- .../main/resources/captions_ps-AF.properties | 24 ++++++++++++++----- .../main/resources/captions_pt-PT.properties | 24 ++++++++++++++----- .../main/resources/captions_ro-RO.properties | 24 ++++++++++++++----- .../main/resources/captions_ru-RU.properties | 24 ++++++++++++++----- .../main/resources/captions_sv-SE.properties | 24 ++++++++++++++----- .../main/resources/captions_sw-KE.properties | 24 ++++++++++++++----- .../main/resources/captions_tr-TR.properties | 24 ++++++++++++++----- .../main/resources/captions_uk-UA.properties | 24 ++++++++++++++----- .../main/resources/captions_ur-PK.properties | 24 ++++++++++++++----- .../main/resources/captions_zh-CN.properties | 24 ++++++++++++++----- 35 files changed, 630 insertions(+), 210 deletions(-) diff --git a/sormas-api/src/main/resources/captions_ar-SA.properties b/sormas-api/src/main/resources/captions_ar-SA.properties index 6bc44c954a6..5f4b0a0830b 100644 --- a/sormas-api/src/main/resources/captions_ar-SA.properties +++ b/sormas-api/src/main/resources/captions_ar-SA.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_cs-CZ.properties b/sormas-api/src/main/resources/captions_cs-CZ.properties index 7ba8ccc19cd..6cf91debdd1 100644 --- a/sormas-api/src/main/resources/captions_cs-CZ.properties +++ b/sormas-api/src/main/resources/captions_cs-CZ.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Změnit prioritu # Campaign campaignActiveCampaigns=Aktivní kampaně campaignAllCampaigns=Všechny kampaně +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archivované kampaně campaignNewCampaign=Nová kampaň campaignCampaignData=Data kampaně @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Název podkarty campaignDashboardChartWidth=Šířka v % campaignDashboardChartHeight=Výška v % campaignDashboardOrder=Pořadí +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Hledat kampaň campaignDiagramGroupBy=Seskupit podle Campaign=Kampaň @@ -366,7 +368,8 @@ caseNewCase=Nový případ casePlaceOfStay=Místo pobytu caseActiveCases=Aktivní případy caseArchivedCases=Archivované případy -caseAllCases=Všechny případy +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Případ přenosu caseTransferCases=Případy přenosu caseReferFromPointOfEntry=Viz případ z místa vstupu @@ -688,9 +691,10 @@ contactSelect=Vybrat kontakt contactCreateNew=Vytvořit nový kontakt contactActiveContacts=Aktivní kontakty contactArchivedContacts=Archivované kontakty -contactAllContacts=Všechny kontakty +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Kontakty contactDetailedOverview=Detaily +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Následné návštěvy contactMinusDays=Předchozí contactPlusDays=Další @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Dokumenty nelze nahrát následujícím entitám\: # Event eventActiveEvents=Aktivní události eventArchivedEvents=Archivované události -eventAllEvents=Všechny události +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Aktivní skupiny eventArchivedGroups=Archivované skupiny +eventDeletedEvents = Deleted events eventAllGroups=Všechny skupiny eventEventActions=Akce události eventEventParticipants=Účastníci události @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Přidat účastníka eventParticipantContactCountOnlyWithSourceCaseInEvent=Počítá pouze kontakty, jejichž zdrojový případ souvisí s touto událostí eventParticipantSelect=Vyberte účastníka události eventParticipantCreateNew=Vytvořit nového účastníka události +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Aktivní účastníci události -eventParticipantAllEventParticipants=Všichni účastníci události +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Účastníci archivované události EventParticipant=Účastník události EventParticipant.contactCount=Počet kontaktů @@ -1846,6 +1852,7 @@ Region.externalID=Externí ID Region.country=Země # Sample sampleCreateNew=Vytvořit nový vzorek +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Vytvořit výsledek testu pro tento vzorek sampleNewSample=Nový vzorek sampleNoSamplesForCase=Pro tento případ nejsou k dispozici žádné vzorky @@ -1869,7 +1876,7 @@ sampleShipped=Odesláno sampleSpecimenNotAdequate=Neadekvátní vzorek sampleActiveSamples=Aktivní vzorky sampleArchivedSamples=Archivované vzorky -sampleAllSamples=Všechny vzorky +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Typ vzorku Sample=Vzorek Sample.additionalTestingRequested=Požadovat provedení dalších testů? @@ -2041,6 +2048,10 @@ Immunization.district=Okres Immunization.community=Komunita Immunization.changeDate=Datum poslední změny Immunization.creationDate=Datum vytvoření +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Seznam imunizací linkImmunizationToCaseButton=Odkaz na Případ openLinkedCaseToImmunizationButton=Otevřít případ @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Pouze položky převedeny na případ travelEntryOpenResultingCase=Otevřít případ tohoto cestovního vstupu travelEntryActiveTravelEntries=Aktivní cestovní vstupy travelEntryArchivedTravelEntries=Archivované cestovní vstupy -travelEntryAllTravelEntries=Všechny cestovní vstupy +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=Pro tuto osobu nejsou žádné záznamy o vstupech z cestování TravelEntry=Vstup cestování TravelEntry.person=Osoba se vstupem z cestování @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Datum poslední změny TravelEntry.creationDate=Datum vytvoření TravelEntry.deletionReason=Důvod odstranění TravelEntry.otherDeletionReason=Důvod pro odstranění podrobností +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Seznam cestovních vstupů # Treatment treatmentCreateTreatment=Vytvořit léčbu diff --git a/sormas-api/src/main/resources/captions_de-CH.properties b/sormas-api/src/main/resources/captions_de-CH.properties index 79d92514692..238914bbfce 100644 --- a/sormas-api/src/main/resources/captions_de-CH.properties +++ b/sormas-api/src/main/resources/captions_de-CH.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Priorität ändern # Campaign campaignActiveCampaigns=Aktive Kampagnen campaignAllCampaigns=Alle Kampagnen +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archivierte Kampagnen campaignNewCampaign=Neue Kampagne campaignCampaignData=Kampagnendaten @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Breite in % campaignDashboardChartHeight=Höhe in % campaignDashboardOrder=Verfügung +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Kampagne suchen campaignDiagramGroupBy=Gruppieren nach Campaign=Kampagne @@ -366,7 +368,8 @@ caseNewCase=Neuer Fall casePlaceOfStay=Aufenthaltsort caseActiveCases=Aktive Fälle caseArchivedCases=Archivierte Fälle -caseAllCases=Alle Fälle +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Fall übertragen caseTransferCases=Fälle übertragen caseReferFromPointOfEntry=Fall vom Einreiseort weiterleiten @@ -688,9 +691,10 @@ contactSelect=Kontakt auswählen contactCreateNew=Neuen Kontakt erstellen contactActiveContacts=Aktive Kontakte contactArchivedContacts=Archivierte Kontakte -contactAllContacts=Alle Kontakte +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Kontakte contactDetailedOverview=Detailliert +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up/Nachverfolgung-Anrufe contactMinusDays=Vorheriger contactPlusDays=Weiter @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Dokumente konnten nicht in die folgenden Entitäten # Event eventActiveEvents=Aktive Ereignisse eventArchivedEvents=Archivierte Ereignisse -eventAllEvents=Alle Ereignisse +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Aktive Gruppen eventArchivedGroups=Archivierte Gruppen +eventDeletedEvents = Deleted events eventAllGroups=Alle Gruppen eventEventActions=Ereignisaktionen eventEventParticipants=Ereignisteilnehmer @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Ereignisteilnehmer hinzufügen eventParticipantContactCountOnlyWithSourceCaseInEvent=Zählt nur Kontakte, deren Indexfall mit diesem Ereignis verbunden ist eventParticipantSelect=Ereignisteilnehmer auswählen eventParticipantCreateNew=Neuen Ereignisteilnehmer erstellen +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Aktive Ereignisteilnehmer -eventParticipantAllEventParticipants=Alle Ereignisteilnehmer +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archivierte Ereignisteilnehmer EventParticipant=Ereignisteilnehmer EventParticipant.contactCount=Kontaktzahl @@ -1846,6 +1852,7 @@ Region.externalID=Externe ID Region.country=Land # Sample sampleCreateNew=Neue Probe erstellen +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Testergebnis für diese Probe jetzt erstellen sampleNewSample=Neue Probe sampleNoSamplesForCase=Es gibt keine Proben für diesen Fall @@ -1869,7 +1876,7 @@ sampleShipped=Versandt sampleSpecimenNotAdequate=Probe nicht sampleActiveSamples=Aktive Proben sampleArchivedSamples=Archivierte Proben -sampleAllSamples=Alle Proben +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Probenart Sample=Probe Sample.additionalTestingRequested=Weitere Tests anfordern? @@ -2041,6 +2048,10 @@ Immunization.district=Bezirk Immunization.community=Gemeinde Immunization.changeDate=Datum der letzten Änderung Immunization.creationDate=Erstellungsdatum +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunisierungsliste linkImmunizationToCaseButton=Fall verknüpfen openLinkedCaseToImmunizationButton=Fall öffnen @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Nur in Fälle konvertierte Einreisen travelEntryOpenResultingCase=Fall zu dieser Einreise öffnen travelEntryActiveTravelEntries=Aktive Einreisen travelEntryArchivedTravelEntries=Archivierte Einreisen -travelEntryAllTravelEntries=Alle Einreisen +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=Es gibt keine Einreisen für diese Person TravelEntry=Einreise TravelEntry.person=Einreiseperson @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Datum der letzten Änderung TravelEntry.creationDate=Erstellungsdatum TravelEntry.deletionReason=Grund des Löschens TravelEntry.otherDeletionReason=Details zum Grund des Löschens +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Einreise-Liste # Treatment treatmentCreateTreatment=Behandlung erstellen diff --git a/sormas-api/src/main/resources/captions_de-DE.properties b/sormas-api/src/main/resources/captions_de-DE.properties index 143b876b5d1..96907a01314 100644 --- a/sormas-api/src/main/resources/captions_de-DE.properties +++ b/sormas-api/src/main/resources/captions_de-DE.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Priorität ändern # Campaign campaignActiveCampaigns=Aktive Kampagnen campaignAllCampaigns=Alle Kampagnen +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archivierte Kampagnen campaignNewCampaign=Neue Kampagne campaignCampaignData=Kampagnendaten @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Unterregistername campaignDashboardChartWidth=Breite in % campaignDashboardChartHeight=Höhe in % campaignDashboardOrder=Verfügung +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Kampagne suchen campaignDiagramGroupBy=Gruppieren nach Campaign=Kampagne @@ -366,7 +368,8 @@ caseNewCase=Neuer Fall casePlaceOfStay=Aufenthaltsort caseActiveCases=Aktive Fälle caseArchivedCases=Abgeschlossene Fälle -caseAllCases=Alle Fälle +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Fall übertragen caseTransferCases=Fälle übertragen caseReferFromPointOfEntry=Fall vom Einreiseort weiterleiten @@ -688,9 +691,10 @@ contactSelect=Kontakt auswählen contactCreateNew=Neuen Kontakt erstellen contactActiveContacts=Aktive Kontakte contactArchivedContacts=Abgeschlossene Kontakte -contactAllContacts=Alle Kontakte +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Kontakte contactDetailedOverview=Detailliert +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up/Nachverfolgung-Anrufe contactMinusDays=Vorheriger contactPlusDays=Weiter @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Dokumente konnten nicht in die folgenden Entitäten # Event eventActiveEvents=Aktive Ereignisse eventArchivedEvents=Abgeschlossene Ereignisse -eventAllEvents=Alle Ereignisse +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Aktive Gruppen eventArchivedGroups=Archivierte Gruppen +eventDeletedEvents = Deleted events eventAllGroups=Alle Gruppen eventEventActions=Ereignisaktionen eventEventParticipants=Ereignisteilnehmer @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Ereignisteilnehmer hinzufügen eventParticipantContactCountOnlyWithSourceCaseInEvent=Zählt nur Kontakte, deren Indexfall mit diesem Ereignis verbunden ist eventParticipantSelect=Ereignisteilnehmer auswählen eventParticipantCreateNew=Neuen Ereignisteilnehmer erstellen +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Aktive Ereignisteilnehmer -eventParticipantAllEventParticipants=Alle Ereignisteilnehmer +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Abgeschlossene Ereignisteilnehmer EventParticipant=Ereignisteilnehmer EventParticipant.contactCount=Anzahl der Kontakte @@ -1846,6 +1852,7 @@ Region.externalID=Externe ID Region.country=Land # Sample sampleCreateNew=Neue Probe erstellen +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Testergebnis für diese Probe jetzt erstellen sampleNewSample=Neue Probe sampleNoSamplesForCase=Es gibt keine Proben für diesen Fall @@ -1869,7 +1876,7 @@ sampleShipped=Versandt sampleSpecimenNotAdequate=Probe nicht sampleActiveSamples=Aktive Proben sampleArchivedSamples=Archivierte Proben -sampleAllSamples=Alle Proben +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Probenart Sample=Probe Sample.additionalTestingRequested=Weitere Tests anfordern? @@ -2041,6 +2048,10 @@ Immunization.district=Landkreis/Kreisfreie Stadt Immunization.community=Gemeinde Immunization.changeDate=Datum der letzten Änderung Immunization.creationDate=Erstellungsdatum +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunisierungsliste linkImmunizationToCaseButton=Fall verknüpfen openLinkedCaseToImmunizationButton=Fall öffnen @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Nur in Fälle konvertierte Einreisen travelEntryOpenResultingCase=Fall zu dieser Einreise öffnen travelEntryActiveTravelEntries=Aktive Einreisen travelEntryArchivedTravelEntries=Abgeschlossene Einreisen -travelEntryAllTravelEntries=Alle Einreisen +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=Es gibt keine Einreisen für diese Person TravelEntry=Einreise TravelEntry.person=Einreiseperson @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Datum der letzten Änderung TravelEntry.creationDate=Erstellungsdatum TravelEntry.deletionReason=Grund des Löschens TravelEntry.otherDeletionReason=Details zum Grund des Löschens +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Einreise-Liste # Treatment treatmentCreateTreatment=Behandlung erstellen diff --git a/sormas-api/src/main/resources/captions_en-AF.properties b/sormas-api/src/main/resources/captions_en-AF.properties index fbf259cee95..6eaf711812f 100644 --- a/sormas-api/src/main/resources/captions_en-AF.properties +++ b/sormas-api/src/main/resources/captions_en-AF.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_en-GH.properties b/sormas-api/src/main/resources/captions_en-GH.properties index 75ab19777e3..507578dd975 100644 --- a/sormas-api/src/main/resources/captions_en-GH.properties +++ b/sormas-api/src/main/resources/captions_en-GH.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_en-NG.properties b/sormas-api/src/main/resources/captions_en-NG.properties index 036ae4b89c3..7fa64e190a2 100644 --- a/sormas-api/src/main/resources/captions_en-NG.properties +++ b/sormas-api/src/main/resources/captions_en-NG.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_es-CU.properties b/sormas-api/src/main/resources/captions_es-CU.properties index b71324614f5..45563920100 100644 --- a/sormas-api/src/main/resources/captions_es-CU.properties +++ b/sormas-api/src/main/resources/captions_es-CU.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Cambiar prioridad # Campaign campaignActiveCampaigns=Campañas activas campaignAllCampaigns=Todas las campañas +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Campañas archivadas campaignNewCampaign=Nueva campaña campaignCampaignData=Datos de campaña @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Nombre de sub-pestaña campaignDashboardChartWidth=Ancho en % campaignDashboardChartHeight=Altura en % campaignDashboardOrder=Pedido +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Buscar campaña campaignDiagramGroupBy=Agrupar por Campaign=Campaña @@ -366,7 +368,8 @@ caseNewCase=Nuevo caso casePlaceOfStay=Lugar de estancia caseActiveCases=Casos activos caseArchivedCases=Casos archivados -caseAllCases=Todos los casos +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transferir caso caseTransferCases=Transferir casos caseReferFromPointOfEntry=Remitir caso desde punto de entrada @@ -688,9 +691,10 @@ contactSelect=Seleccionar contacto contactCreateNew=Crear nuevo contacto contactActiveContacts=Contactos activos contactArchivedContacts=Contactos archivados -contactAllContacts=Todos los contactos +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contactos contactDetailedOverview=Detallado +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Visitas de seguimiento contactMinusDays=Anterior contactPlusDays=Siguiente @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=No se pudieron subir documentos a las siguientes en # Event eventActiveEvents=Eventos activos eventArchivedEvents=Eventos archivados -eventAllEvents=Todos los eventos +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Grupos activos eventArchivedGroups=Grupos archivados +eventDeletedEvents = Deleted events eventAllGroups=Todos los grupos eventEventActions=Acciones del evento eventEventParticipants=Participantes del evento @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Añadir participante eventParticipantContactCountOnlyWithSourceCaseInEvent=Solo cuenta contactos cuyo caso de origen está relacionado a este evento eventParticipantSelect=Seleccionar participante de evento eventParticipantCreateNew=Crear nuevo participante de evento +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Participantes de evento activos -eventParticipantAllEventParticipants=Todos los participantes de evento +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Participantes de evento archivados EventParticipant=Participante de evento EventParticipant.contactCount=Número de contactos @@ -1846,6 +1852,7 @@ Region.externalID=ID externa Region.country=País # Sample sampleCreateNew=Crear nueva muestra +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Crear resultado de prueba para esta muestra ahora sampleNewSample=Nueva muestra sampleNoSamplesForCase=No hay muestras de este caso @@ -1869,7 +1876,7 @@ sampleShipped=Enviada sampleSpecimenNotAdequate=Espécimen no adecuado sampleActiveSamples=Muestras activas sampleArchivedSamples=Muestras archivadas -sampleAllSamples=Todas las muestras +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Tipo de muestra Sample=Muestra Sample.additionalTestingRequested=¿Solicitar la realización de pruebas adicionales? @@ -2041,6 +2048,10 @@ Immunization.district=Municipio Immunization.community=Área de salud Immunization.changeDate=Fecha del último cambio Immunization.creationDate=Fecha de creación +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Lista de inmunizaciones linkImmunizationToCaseButton=Vincular caso openLinkedCaseToImmunizationButton=Abrir caso @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Sólo entradas convertidas en caso travelEntryOpenResultingCase=Abrir caso de esta entrada de viaje travelEntryActiveTravelEntries=Entradas de viaje activas travelEntryArchivedTravelEntries=Entradas de viaje archivadas -travelEntryAllTravelEntries=Todas las entradas de viaje +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=No hay entradas de viaje para esta persona TravelEntry=Entrada de viaje TravelEntry.person=Persona de entrada de viaje @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Fecha del último cambio TravelEntry.creationDate=Fecha de creación TravelEntry.deletionReason=Motivo de eliminación TravelEntry.otherDeletionReason=Detalles del motivo de eliminación +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Lista de entradas de viaje # Treatment treatmentCreateTreatment=Crear tratamiento diff --git a/sormas-api/src/main/resources/captions_es-EC.properties b/sormas-api/src/main/resources/captions_es-EC.properties index 13fc4b89c15..eeb871de5dd 100644 --- a/sormas-api/src/main/resources/captions_es-EC.properties +++ b/sormas-api/src/main/resources/captions_es-EC.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=Nuevo caso casePlaceOfStay=Place of stay caseActiveCases=Casos activos caseArchivedCases=Casos archivados -caseAllCases=Todos los casos +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transferir caso caseTransferCases=Casos transferidos caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Seleccionar contacto contactCreateNew=Crear nuevo contacto contactActiveContacts=Contactos activos contactArchivedContacts=Contactos archivados -contactAllContacts=Todos los contactos +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contactos contactDetailedOverview=Detallado +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Visitas de seguimiento contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Eventos activos eventArchivedEvents=Eventos archivados -eventAllEvents=Todos los eventos +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Participantes del evento @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=Id externo Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=Nueva muestra sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Enviado sampleSpecimenNotAdequate=Espécimen no adecuado sampleActiveSamples=Muestras activas sampleArchivedSamples=Muestras archivadas -sampleAllSamples=Todas las muestras +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Muestra Sample.additionalTestingRequested=¿Solicitar pruebas adicionales para realizar? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Crear tratamiento diff --git a/sormas-api/src/main/resources/captions_es-ES.properties b/sormas-api/src/main/resources/captions_es-ES.properties index cb0cdd23811..abf1a6c5015 100644 --- a/sormas-api/src/main/resources/captions_es-ES.properties +++ b/sormas-api/src/main/resources/captions_es-ES.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_fa-AF.properties b/sormas-api/src/main/resources/captions_fa-AF.properties index f0e61fec6bf..c799eeb21ed 100644 --- a/sormas-api/src/main/resources/captions_fa-AF.properties +++ b/sormas-api/src/main/resources/captions_fa-AF.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=کمپاین های فعال campaignAllCampaigns=همه کمپاین ها +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=کمپاین های ارشیف شده campaignNewCampaign=کمپاین جدید campaignCampaignData=ارقام کمپاین @@ -311,6 +312,7 @@ campaignDashboardSubTabName=نام تب فرعی دشبورد campaignDashboardChartWidth=وسعت چارت دشبورد campaignDashboardChartHeight=ارتفاغ چارت دشبورد campaignDashboardOrder=تنظیم دشبورد +campaignDeletedCampaigns=Deleted campaigns campaignSearch=جستجو campaignDiagramGroupBy=گروپ کردن دیاگرام بواسطه\: Campaign=کمپاین @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=شناسنامه بیرونی Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_fi-FI.properties b/sormas-api/src/main/resources/captions_fi-FI.properties index 197b65217dd..cd39003c3d6 100644 --- a/sormas-api/src/main/resources/captions_fi-FI.properties +++ b/sormas-api/src/main/resources/captions_fi-FI.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Aktiiviset kampanjat campaignAllCampaigns=Kaikka kampanjat +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Arkistoidut kampanjat campaignNewCampaign=Uusi kampanja campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Kampanja @@ -366,7 +368,8 @@ caseNewCase=Uusi potilas casePlaceOfStay=Place of stay caseActiveCases=Tämänhetkiset potilaat caseArchivedCases=Arkistoidut potilaat -caseAllCases=Kaikki potilaat +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Siirrä potilas caseTransferCases=Siirrä useita potilaita caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Valitse kontakti contactCreateNew=Luo uusi kontakti contactActiveContacts=Aktiiviset kontaktit contactArchivedContacts=Arkistoidut kontaktit -contactAllContacts=Kaikki kontaktit +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Kontaktit contactDetailedOverview=Tarkemmat tiedot +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Seurantakäynnit contactMinusDays=Edellinen contactPlusDays=Seuraava @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Aktiiviset tapahtumat eventArchivedEvents=Arkistoidut tapahtumat -eventAllEvents=Kaikki tapahtumat +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Tapahtuman osallistujat @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=Ulkoinen tunniste Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Luo testitulos tälle näytteelle nyt sampleNewSample=Uusi näyte sampleNoSamplesForCase=Tälle potilaalle ei ole näytteitä @@ -1869,7 +1876,7 @@ sampleShipped=Lähetetty sampleSpecimenNotAdequate=Näyte ei ole riittävä sampleActiveSamples=Tämänhetkiset näytteet sampleArchivedSamples=Arkistoidut näytteet -sampleAllSamples=Kaikki näytteet +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Näytetyyppi Sample=Näyte Sample.additionalTestingRequested=Vaaditaanko lisätestejä suoritettavaksi? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Luo hoito diff --git a/sormas-api/src/main/resources/captions_fil-PH.properties b/sormas-api/src/main/resources/captions_fil-PH.properties index cb0cdd23811..abf1a6c5015 100644 --- a/sormas-api/src/main/resources/captions_fil-PH.properties +++ b/sormas-api/src/main/resources/captions_fil-PH.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_fj-FJ.properties b/sormas-api/src/main/resources/captions_fj-FJ.properties index cb0cdd23811..abf1a6c5015 100644 --- a/sormas-api/src/main/resources/captions_fj-FJ.properties +++ b/sormas-api/src/main/resources/captions_fj-FJ.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_fr-CH.properties b/sormas-api/src/main/resources/captions_fr-CH.properties index 6da88f00878..354970f28d7 100644 --- a/sormas-api/src/main/resources/captions_fr-CH.properties +++ b/sormas-api/src/main/resources/captions_fr-CH.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Changer le niveau de priorité # Campaign campaignActiveCampaigns=Campagnes actives campaignAllCampaigns=Toutes les campagnes +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Campagnes archivées campaignNewCampaign=Nouvelle campagne campaignCampaignData=Données de campagne @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Nom du sous-onglet campaignDashboardChartWidth=Largeur en % campaignDashboardChartHeight=Hauteur en % campaignDashboardOrder=Ordre +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Sélectionner la campagne campaignDiagramGroupBy=Regrouper par Campaign=Campagne @@ -366,7 +368,8 @@ caseNewCase=Nouveau Cas casePlaceOfStay=Lieu de résidence caseActiveCases=Cas actifs caseArchivedCases=Cas archivés -caseAllCases=Tous les cas +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Boîte de transfert caseTransferCases=Transférer des cas caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Sélectionner un contact contactCreateNew=Créer un nouveau contact contactActiveContacts=Contacts actifs contactArchivedContacts=Contacts archivés -contactAllContacts=Tous les contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Les contacts contactDetailedOverview=Détaillé +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Visites de suivi contactMinusDays=- 8 jours contactPlusDays=+ 8 jours @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Événements actifs eventArchivedEvents=Événements archivés -eventAllEvents=Tous les événements +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Actions de l'événement eventEventParticipants=Participants à l'événement @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Ajouter un participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Uniquement les contacts dont le cas source est lié à l'événement spécifié eventParticipantSelect=Sélectionner un participant eventParticipantCreateNew=Créer un nouveau participant à l'événement +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Personnes impliquées EventParticipant.contactCount=Nombre de contacts @@ -1846,6 +1852,7 @@ Region.externalID=Identification externe Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Créer un résultat de test pour cet échantillon maintenant sampleNewSample=Nouveau échantillon sampleNoSamplesForCase=Il n’y a pas d’échantillons pour ce cas @@ -1869,7 +1876,7 @@ sampleShipped=Envoyé sampleSpecimenNotAdequate=Spécimen non adéquat sampleActiveSamples=Échantillons actifs sampleArchivedSamples=Échantillons archivés -sampleAllSamples=Tous les échantillons +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Type d'échantillon Sample=Échantillon Sample.additionalTestingRequested=Demander des tests supplémentaires à effectuer ? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Créer un traitement diff --git a/sormas-api/src/main/resources/captions_fr-FR.properties b/sormas-api/src/main/resources/captions_fr-FR.properties index 81df42c7820..d3972a0b5d9 100644 --- a/sormas-api/src/main/resources/captions_fr-FR.properties +++ b/sormas-api/src/main/resources/captions_fr-FR.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Changer le niveau de priorité # Campaign campaignActiveCampaigns=Campagnes actives campaignAllCampaigns=Toutes les campagnes +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Campagnes archivées campaignNewCampaign=Nouvelle campagne campaignCampaignData=Données de la campagne @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Nom du sous-onglet campaignDashboardChartWidth=Largeur en % campaignDashboardChartHeight=Hauteur en % campaignDashboardOrder=Ordre +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Sélectionner la campagne campaignDiagramGroupBy=Regrouper par Campaign=Campagne @@ -366,7 +368,8 @@ caseNewCase=Nouveau Cas casePlaceOfStay=Lieu du séjour caseActiveCases=Cas actifs caseArchivedCases=Cas archivés -caseAllCases=Tous les cas +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transférer ce cas caseTransferCases=Transférer des cas caseReferFromPointOfEntry=Référez le cas à partir du point d'entrée @@ -688,9 +691,10 @@ contactSelect=Sélectionner un contact contactCreateNew=Créer un nouveau contact contactActiveContacts=Contacts actifs contactArchivedContacts=Contacts archivés -contactAllContacts=Tous les contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Détaillé +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Visites de suivi contactMinusDays=Précédent contactPlusDays=Suivant @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Les documents n'ont pas pu être téléchargés dan # Event eventActiveEvents=Événements actifs eventArchivedEvents=Événements archivés -eventAllEvents=Tous les événements +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Groupes actifs eventArchivedGroups=Groupes archivés +eventDeletedEvents = Deleted events eventAllGroups=Tous les groupes eventEventActions=Actions de l'événement eventEventParticipants=Participants à l'événement @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Ajouter un participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Seulement les contacts avec le cas source lié à l'événement spécifié eventParticipantSelect=Sélectionner un participant eventParticipantCreateNew=Créer un nouveau participant à l'événement +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Participant à l'événement EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=ID externe Region.country=Pays # Sample sampleCreateNew=Créer un nouvel échantillon +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Créer de suite un résultat de test pour cet échantillon sampleNewSample=Nouvel échantillon sampleNoSamplesForCase=Il n’y a pas d’échantillons pour ce cas @@ -1869,7 +1876,7 @@ sampleShipped=Envoyé sampleSpecimenNotAdequate=Spécimen non adéquat sampleActiveSamples=Échantillons actifs sampleArchivedSamples=Échantillons archivés -sampleAllSamples=Tous les échantillons +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Type d'échantillon Sample=Échantillon Sample.additionalTestingRequested=Tests supplémentaires à effectuer ? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Liste des immunisations linkImmunizationToCaseButton=Lier le cas openLinkedCaseToImmunizationButton=Ouvrir le cas @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=Il n'y a pas de voyages répertoriés pour cette personne TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Créer un traitement diff --git a/sormas-api/src/main/resources/captions_hi-IN.properties b/sormas-api/src/main/resources/captions_hi-IN.properties index cb0cdd23811..abf1a6c5015 100644 --- a/sormas-api/src/main/resources/captions_hi-IN.properties +++ b/sormas-api/src/main/resources/captions_hi-IN.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_hr-HR.properties b/sormas-api/src/main/resources/captions_hr-HR.properties index cb0cdd23811..abf1a6c5015 100644 --- a/sormas-api/src/main/resources/captions_hr-HR.properties +++ b/sormas-api/src/main/resources/captions_hr-HR.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_it-CH.properties b/sormas-api/src/main/resources/captions_it-CH.properties index 68ce85579b9..bec7d4d437f 100644 --- a/sormas-api/src/main/resources/captions_it-CH.properties +++ b/sormas-api/src/main/resources/captions_it-CH.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Campagne attive campaignAllCampaigns=Tutte le campagne +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Campagne archiviate campaignNewCampaign=Nuova campagna campaignCampaignData=Dati campagna @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campagna @@ -366,7 +368,8 @@ caseNewCase=Nuovo caso casePlaceOfStay=Luogo di soggiorno caseActiveCases=Casi attivi caseArchivedCases=Casi archiviati -caseAllCases=Tutti i casi +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Trasferisci caso caseTransferCases=Trasferisci casi caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Seleziona contatto contactCreateNew=Crea un nuovo contatto contactActiveContacts=Contatti attivi contactArchivedContacts=Contatti archiviati -contactAllContacts=Tutti i contatti +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contatti contactDetailedOverview=Dettagliato +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Telefonate di follow-up contactMinusDays=Indietro contactPlusDays=Successivo @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Eventi attivi eventArchivedEvents=Eventi archiviati -eventAllEvents=Tutti gli eventi +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Azioni Evento eventEventParticipants=Partecipanti dell'evento @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Partecipante all'evento EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=ID esterno Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Crea risultato test per questo campione ora sampleNewSample=Nuovo campione sampleNoSamplesForCase=Non ci sono campioni per questo caso @@ -1869,7 +1876,7 @@ sampleShipped=Spedito sampleSpecimenNotAdequate=Esemplare non adeguato sampleActiveSamples=Campioni attivi sampleArchivedSamples=Campioni archiviati -sampleAllSamples=Tutti i campioni +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Tipo di campione Sample=Campione Sample.additionalTestingRequested=Richiedi ulteriori test? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Crea trattamento diff --git a/sormas-api/src/main/resources/captions_it-IT.properties b/sormas-api/src/main/resources/captions_it-IT.properties index 05c27b631ad..56ddd1da907 100644 --- a/sormas-api/src/main/resources/captions_it-IT.properties +++ b/sormas-api/src/main/resources/captions_it-IT.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Campagne attive campaignAllCampaigns=Tutte le campagne +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Campagne archiviate campaignNewCampaign=Nuova campagna campaignCampaignData=Dati campagna @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campagna @@ -366,7 +368,8 @@ caseNewCase=Nuovo caso casePlaceOfStay=Place of stay caseActiveCases=Casi attivi caseArchivedCases=Casi archiviati -caseAllCases=Tutti i casi +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Trasferisci caso caseTransferCases=Trasferisci casi caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Seleziona contatto contactCreateNew=Crea un nuovo contatto contactActiveContacts=Contatti attivi contactArchivedContacts=Contatti archiviati -contactAllContacts=Tutti i contatti +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contatti contactDetailedOverview=Dettagliato +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Telefonate di follow-up contactMinusDays=Indietro contactPlusDays=Successivo @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Eventi attivi eventArchivedEvents=Eventi archiviati -eventAllEvents=Tutti gli eventi +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Partecipanti dell'evento @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Partecipante all'evento EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=ID esterno Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Crea risultato test per questo campione ora sampleNewSample=Nuovo campione sampleNoSamplesForCase=Non ci sono campioni per questo caso @@ -1869,7 +1876,7 @@ sampleShipped=Spedito sampleSpecimenNotAdequate=Esemplare non adeguato sampleActiveSamples=Campioni attivi sampleArchivedSamples=Campioni archiviati -sampleAllSamples=Tutti i campioni +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Tipo di campione Sample=Campione Sample.additionalTestingRequested=Richiedi ulteriori test? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Crea trattamento diff --git a/sormas-api/src/main/resources/captions_ja-JP.properties b/sormas-api/src/main/resources/captions_ja-JP.properties index cb0cdd23811..abf1a6c5015 100644 --- a/sormas-api/src/main/resources/captions_ja-JP.properties +++ b/sormas-api/src/main/resources/captions_ja-JP.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_ne-NP.properties b/sormas-api/src/main/resources/captions_ne-NP.properties index 6bc44c954a6..5f4b0a0830b 100644 --- a/sormas-api/src/main/resources/captions_ne-NP.properties +++ b/sormas-api/src/main/resources/captions_ne-NP.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_nl-NL.properties b/sormas-api/src/main/resources/captions_nl-NL.properties index 04ac985a0f3..c62d1707c32 100644 --- a/sormas-api/src/main/resources/captions_nl-NL.properties +++ b/sormas-api/src/main/resources/captions_nl-NL.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_no-NO.properties b/sormas-api/src/main/resources/captions_no-NO.properties index cb0cdd23811..abf1a6c5015 100644 --- a/sormas-api/src/main/resources/captions_no-NO.properties +++ b/sormas-api/src/main/resources/captions_no-NO.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_pl-PL.properties b/sormas-api/src/main/resources/captions_pl-PL.properties index cb0cdd23811..abf1a6c5015 100644 --- a/sormas-api/src/main/resources/captions_pl-PL.properties +++ b/sormas-api/src/main/resources/captions_pl-PL.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_ps-AF.properties b/sormas-api/src/main/resources/captions_ps-AF.properties index d05f9da6564..5c001501992 100644 --- a/sormas-api/src/main/resources/captions_ps-AF.properties +++ b/sormas-api/src/main/resources/captions_ps-AF.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=فعال کمپاینونه campaignAllCampaigns=ټول کمپاینونه +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=ارشیف شوي کمپاینونه campaignNewCampaign=نوی کمپاین campaignCampaignData=د کمپاین ارقام @@ -311,6 +312,7 @@ campaignDashboardSubTabName=د ډشبورډ د فرعی ټب نوم campaignDashboardChartWidth=د ډ شبورډ د چارټ پراښوالی campaignDashboardChartHeight=د ډشبورډ د چارټ جګوالی campaignDashboardOrder=د ډشبورډ منظموالی +campaignDeletedCampaigns=Deleted campaigns campaignSearch=پلټنه campaignDiagramGroupBy=د ډیاګرام ګروپ کول پواسطه د Campaign=کمپاین @@ -366,7 +368,8 @@ caseNewCase=نوې پیښه casePlaceOfStay=د اوسېدو ځای caseActiveCases=فعاله پیښه caseArchivedCases=ظبط شوي پیښې -caseAllCases=ټولې پیښې +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=رجعت شوې پیښه caseTransferCases=رجعت شوې پیښه caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=د تماسي شخص انتخاب contactCreateNew=د نوي تماس ایجادول contactActiveContacts=فعال تماسونه contactArchivedContacts=ارشیف شوي تماسونه یا اړیکي -contactAllContacts=ټول تماسونه +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=تماسونه contactDetailedOverview=توضیحات +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=تعقیبي ملاقاتونه contactMinusDays=پخواني جارنې contactPlusDays=راتلونکې څارمې @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=بهرنی هویت Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_pt-PT.properties b/sormas-api/src/main/resources/captions_pt-PT.properties index 7de4578215a..3739861fb14 100644 --- a/sormas-api/src/main/resources/captions_pt-PT.properties +++ b/sormas-api/src/main/resources/captions_pt-PT.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_ro-RO.properties b/sormas-api/src/main/resources/captions_ro-RO.properties index cb0cdd23811..abf1a6c5015 100644 --- a/sormas-api/src/main/resources/captions_ro-RO.properties +++ b/sormas-api/src/main/resources/captions_ro-RO.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_ru-RU.properties b/sormas-api/src/main/resources/captions_ru-RU.properties index 0a2f5ef0c36..da4c648e705 100644 --- a/sormas-api/src/main/resources/captions_ru-RU.properties +++ b/sormas-api/src/main/resources/captions_ru-RU.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_sv-SE.properties b/sormas-api/src/main/resources/captions_sv-SE.properties index cb0cdd23811..abf1a6c5015 100644 --- a/sormas-api/src/main/resources/captions_sv-SE.properties +++ b/sormas-api/src/main/resources/captions_sv-SE.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_sw-KE.properties b/sormas-api/src/main/resources/captions_sw-KE.properties index cb0cdd23811..abf1a6c5015 100644 --- a/sormas-api/src/main/resources/captions_sw-KE.properties +++ b/sormas-api/src/main/resources/captions_sw-KE.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_tr-TR.properties b/sormas-api/src/main/resources/captions_tr-TR.properties index cb0cdd23811..abf1a6c5015 100644 --- a/sormas-api/src/main/resources/captions_tr-TR.properties +++ b/sormas-api/src/main/resources/captions_tr-TR.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_uk-UA.properties b/sormas-api/src/main/resources/captions_uk-UA.properties index cb0cdd23811..abf1a6c5015 100644 --- a/sormas-api/src/main/resources/captions_uk-UA.properties +++ b/sormas-api/src/main/resources/captions_uk-UA.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=New case casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=All cases +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=Transfer case caseTransferCases=Transfer cases caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment diff --git a/sormas-api/src/main/resources/captions_ur-PK.properties b/sormas-api/src/main/resources/captions_ur-PK.properties index dae0f379c5f..37378014904 100644 --- a/sormas-api/src/main/resources/captions_ur-PK.properties +++ b/sormas-api/src/main/resources/captions_ur-PK.properties @@ -297,6 +297,7 @@ bulkTaskPriority=ترجیح تبدیل کریں # Campaign campaignActiveCampaigns=فعال مہمات campaignAllCampaigns=تمام مہمات +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=آرکائیوڈ مہمات campaignNewCampaign=نئی مہم campaignCampaignData=مہم کا ڈیٹا @@ -311,6 +312,7 @@ campaignDashboardSubTabName=سب ٹیب کا نام campaignDashboardChartWidth=% میں چوڑائی campaignDashboardChartHeight=اونچائی % میں campaignDashboardOrder=احکامات +campaignDeletedCampaigns=Deleted campaigns campaignSearch=مہم تلاش کریں campaignDiagramGroupBy=گروپ بمطابق Campaign=مہم @@ -366,7 +368,8 @@ caseNewCase=نئا کیس casePlaceOfStay=قیام کی جگہ caseActiveCases=فعال کیسز caseArchivedCases=آرکائیو کیسز -caseAllCases=تمام کیسز +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=کیس کی منتقلی caseTransferCases=کیسز کی منتقلی caseReferFromPointOfEntry=داخلے کا جگہ سے کیس کا حوالہ دیں @@ -688,9 +691,10 @@ contactSelect=رابطہ منتخب کریں contactCreateNew=نیا ربط بنائیں contactActiveContacts=فعال رابطے contactArchivedContacts=آرکائیوڈ روابط -contactAllContacts=تمام روابط +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=روابط contactDetailedOverview=تفصیلات +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=فالو اپ دورے contactMinusDays=پچھلا contactPlusDays=اگلا @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=درج ذیل اینٹيٹیز پر دستاویز # Event eventActiveEvents=فعال تقریبات eventArchivedEvents=آرکائیو کردہ تقریبات -eventAllEvents=تمام تقریبات +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=فعال گروہ eventArchivedGroups=آرکائیوڈ گروپس +eventDeletedEvents = Deleted events eventAllGroups=تمام گروپس eventEventActions=تقریب کی کارروائیاں eventEventParticipants=تقریب کے شرکاہ @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=شریک شامل کریں eventParticipantContactCountOnlyWithSourceCaseInEvent=صرف ان رابطوں کو شمار کرتا ہے جن کا سورس کیس اس تقریب سے متعلق ہے eventParticipantSelect=تقریب کے شریک کو منتخب کریں eventParticipantCreateNew=تقریب کا نیا شریک بنائیں +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=فعال تقریب کے شرکاء -eventParticipantAllEventParticipants=تمام تقریب کے شرکاء +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=آرکائیو شدہ تقریب کے شرکاء EventParticipant=تقریب حصہ لینے والا EventParticipant.contactCount=رابطے کی تعداد @@ -1846,6 +1852,7 @@ Region.externalID=بیرونی شناخت Region.country=ملک # Sample sampleCreateNew=نیا نمونہ بنائیں +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=اس نمونے کے لیے ابھی ٹیسٹ کا نتیجہ بنائیں sampleNewSample=نیا نمونہ sampleNoSamplesForCase=اس کیس کے لیے کوئی نمونے نہیں ہیں @@ -1869,7 +1876,7 @@ sampleShipped=بھیج دیا گیا sampleSpecimenNotAdequate=نمونہ کافی نہیں ہے sampleActiveSamples=فعال نمونے sampleArchivedSamples=آرکائیوڈ نمونے -sampleAllSamples=تمام نمونے +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=نمونہ کی قسم Sample=نمونہ Sample.additionalTestingRequested=اضافی ٹیسٹ کروانے کی درخواست کریں؟ @@ -2041,6 +2048,10 @@ Immunization.district=ضلع Immunization.community=کمیونیٹی Immunization.changeDate=آخری تبدیلی کی تاریخ Immunization.creationDate=بنانے کی تاریخ +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=امیونائزیشن کی فہرست linkImmunizationToCaseButton=لنک کیس openLinkedCaseToImmunizationButton=کھلا کیس @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=صر فوہ اندراجات، جن کو travelEntryOpenResultingCase=اس ٹریول انٹری کے لۓ کیس اوپن کیس travelEntryActiveTravelEntries=فعال سفری اندراجات travelEntryArchivedTravelEntries=آرکائیوڈ سفری اندراجات -travelEntryAllTravelEntries=تمام سفری اندراجات +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=اس شخص کے لیے کوئی سفری اندراج نہیں ہے TravelEntry=سفری اندراج TravelEntry.person=سفری داخلہ شخص @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=آخری تبدیلی کی تاریخ TravelEntry.creationDate=بنانے کی تاریخ TravelEntry.deletionReason=مٹانے کی وجہ TravelEntry.otherDeletionReason=تفصیلات کو مٹانے کی وجہ +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=سفری اندراجات کی فہرست # Treatment treatmentCreateTreatment=علاج کا انداج کریں diff --git a/sormas-api/src/main/resources/captions_zh-CN.properties b/sormas-api/src/main/resources/captions_zh-CN.properties index 47aca9f03ed..6fd446e7df0 100644 --- a/sormas-api/src/main/resources/captions_zh-CN.properties +++ b/sormas-api/src/main/resources/captions_zh-CN.properties @@ -297,6 +297,7 @@ bulkTaskPriority=Change priority # Campaign campaignActiveCampaigns=Active campaigns campaignAllCampaigns=All campaigns +campaignAllActiveAndArchivedCampaigns=All active and archived campaigns campaignArchivedCampaigns=Archived campaigns campaignNewCampaign=New campaign campaignCampaignData=Campaign Data @@ -311,6 +312,7 @@ campaignDashboardSubTabName=Sub-tab name campaignDashboardChartWidth=Width in % campaignDashboardChartHeight=Height in % campaignDashboardOrder=Order +campaignDeletedCampaigns=Deleted campaigns campaignSearch=Search Campaign campaignDiagramGroupBy=Group by Campaign=Campaign @@ -366,7 +368,8 @@ caseNewCase=新病例 casePlaceOfStay=Place of stay caseActiveCases=Active cases caseArchivedCases=Archived cases -caseAllCases=全部病例 +caseAllActiveAndArchivedCases=All active and archived cases +caseDeletedCases=Deleted cases caseTransferCase=移交病例 caseTransferCases=移交病例 caseReferFromPointOfEntry=Refer case from point of entry @@ -688,9 +691,10 @@ contactSelect=Select contact contactCreateNew=Create new contact contactActiveContacts=Active contacts contactArchivedContacts=Archived contacts -contactAllContacts=All contacts +contactAllActiveAndArchiveContacts=All active and archived contacts contactContactsOverview=Contacts contactDetailedOverview=Detailed +contactDeletedContacts=Deleted contacts contactFollowUpVisitsOverview=Follow-up Visits contactMinusDays=Previous contactPlusDays=Next @@ -1082,9 +1086,10 @@ DocumentTemplate.notUploaded=Documents could not be uploaded to the following en # Event eventActiveEvents=Active events eventArchivedEvents=Archived events -eventAllEvents=All events +eventAllActiveAndArchivedEvents=All active and archived events eventActiveGroups=Active groups eventArchivedGroups=Archived groups +eventDeletedEvents = Deleted events eventAllGroups=All groups eventEventActions=Event actions eventEventParticipants=Event participants @@ -1229,8 +1234,9 @@ eventParticipantAddPerson=Add participant eventParticipantContactCountOnlyWithSourceCaseInEvent=Only counts contacts whose source case is related to this event eventParticipantSelect=Select event participant eventParticipantCreateNew=Create new event participant +eventParticipantDeletedEventParticipants = Deleted event participants eventParticipantActiveEventParticipants=Active event participants -eventParticipantAllEventParticipants=All event participants +eventParticipantActiveAndArchivedEventParticipants=Active and archived event participants eventParticipantArchivedEventParticipants=Archived event participants EventParticipant=Event participant EventParticipant.contactCount=Contact count @@ -1846,6 +1852,7 @@ Region.externalID=External ID Region.country=Country # Sample sampleCreateNew=Create new sample +sampleDeletedSamples=Deleted samples sampleIncludeTestOnCreation=Create test result for this sample now sampleNewSample=New sample sampleNoSamplesForCase=There are no samples for this case @@ -1869,7 +1876,7 @@ sampleShipped=Shipped sampleSpecimenNotAdequate=Specimen not adequate sampleActiveSamples=Active samples sampleArchivedSamples=Archived samples -sampleAllSamples=All samples +sampleAllActiveAndArchivedSamples=All active and archived samples sampleAssociationType=Sample type Sample=Sample Sample.additionalTestingRequested=Request additional tests to be performed? @@ -2041,6 +2048,10 @@ Immunization.district=District Immunization.community=Community Immunization.changeDate=Date of last change Immunization.creationDate=Creation date +immunizationActiveImmunizations = Active immunizations +immunizationArchivedImmunizations = Archived immunizations +immunizationAllActiveAndArchivedImmunizations = All active and archived immunizations +immunizationDeletedImmunizations = Deleted immunizations immunizationImmunizationsList=Immunizations list linkImmunizationToCaseButton=Link case openLinkedCaseToImmunizationButton=Open case @@ -2315,7 +2326,7 @@ travelEntryOnlyEntriesConvertedToCase=Only entries converted to case travelEntryOpenResultingCase=Open case of this travel entry travelEntryActiveTravelEntries=Active travel entries travelEntryArchivedTravelEntries=Archived travel entries -travelEntryAllTravelEntries=All travel entries +travelEntryAllActiveAndArchivedTravelEntries=All active and archived travel entries travelEntriesNoTravelEntriesForPerson=There are no travel entries for this person TravelEntry=Travel entry TravelEntry.person=Travel entry person @@ -2362,6 +2373,7 @@ TravelEntry.changeDate=Date of last change TravelEntry.creationDate=Creation date TravelEntry.deletionReason=Reason for deletion TravelEntry.otherDeletionReason=Reason for deletion details +TravelEntry.deletedTravelEntries=Deleted travel entries travelEntryTravelEntriesList=Travel entries list # Treatment treatmentCreateTreatment=Create treatment From 44879dedbae59714ac6bc9ecad14a3bf4fe95bad Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Mon, 9 Jan 2023 10:22:54 +0100 Subject: [PATCH 078/166] sorqa-772 --- .../features/sanity/web/Login.feature | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/Login.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/Login.feature index 93fa4eaa509..9edca3201e4 100755 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/Login.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/Login.feature @@ -1,7 +1,7 @@ @UI @Sanity @Login @precon Feature: Login with different type of users - @env_main @LoginMain @testIt + @env_main @LoginMain Scenario Outline: Login with user on Main Environment Given I navigate to SORMAS login page And I check that Login page is correctly displayed in English language @@ -15,7 +15,6 @@ Feature: Login with different type of users Examples: | user | | National User | -# | National Language User | | Contact Supervisor | | Surveillance Officer | | Surveillance Supervisor | @@ -45,7 +44,6 @@ Feature: Login with different type of users Examples: | user | | National User | -# | National Language User | | Contact Supervisor | | Surveillance Officer | | Surveillance Supervisor | @@ -77,4 +75,27 @@ Feature: Login with different type of users Given I navigate to Keycloak Administrator Console Login page Then I log in as Keycloak Admin to Keycloak Administrator Console Then I am logged in Keycloak Administrator Console page - And I click on logout button on Keycloak Administrator Console Page \ No newline at end of file + And I click on logout button on Keycloak Administrator Console Page + + @tmsLink=SORQA-772 @env_main + Scenario: Automatize Login with National Language User on international environment + Given I navigate to SORMAS login page + And I check that Login page is correctly displayed in English language + Then I log in as a National Language User + Then I am logged in + And I check that Surveillance Dashboard header is correctly displayed in German language + Then I click on the User Settings button from navbar + Then I check that Deutsch language is selected in User Settings + And I click on logout button + + @tmsLink=SORQA-772 @env_de + Scenario: Automatize Login with National Language User on german environment + Given I navigate to SORMAS login page + And I check that Login page is correctly displayed in German language + Then I log in as a National Language User + Then I am logged in + And I check that Surveillance Dashboard header is correctly displayed in English language + Then I click on the User Settings button from navbar + Then I check that English language is selected in User Settings + And I click on logout button + From a579da536a182592838550b447104542ef79648c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=A9=20Strysewske?= Date: Mon, 9 Jan 2023 10:41:25 +0100 Subject: [PATCH 079/166] #10436 - Fixed crash for non-pending tasks --- .../sormas/app/task/edit/TaskEditFragment.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/task/edit/TaskEditFragment.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/task/edit/TaskEditFragment.java index 8eac2743db6..1f536990d01 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/task/edit/TaskEditFragment.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/task/edit/TaskEditFragment.java @@ -17,10 +17,10 @@ import static android.view.View.GONE; -import android.view.View; - import java.util.List; +import android.view.View; + import de.symeda.sormas.api.caze.CaseClassification; import de.symeda.sormas.api.task.TaskPriority; import de.symeda.sormas.api.task.TaskStatus; @@ -98,7 +98,7 @@ public Task getPrimaryData() { @Override public boolean isShowSaveAction() { - return record != null && ConfigProvider.getUser().equals(record.getCreatorUser()); + return record != null && ConfigProvider.getUser().equals(record.getCreatorUser()) && record.getTaskStatus() != TaskStatus.PENDING; } @Override @@ -167,11 +167,8 @@ protected void onAfterLayoutBinding(FragmentTaskEditLayoutBinding contentBinding if (!ConfigProvider.getUser().equals(record.getAssigneeUser())) { contentBinding.taskAssigneeReply.setEnabled(false); contentBinding.taskButtonPanel.setVisibility(GONE); - } else { - if (record.getTaskStatus() != TaskStatus.PENDING) { - getBaseEditActivity().getSaveMenu().setVisible(true); - contentBinding.taskButtonPanel.setVisibility(GONE); - } + } else if (record.getTaskStatus() != TaskStatus.PENDING) { + contentBinding.taskButtonPanel.setVisibility(GONE); } contentBinding.taskAssigneeUser.addValueChangedListener(v -> { From aa62529f8102a8c1bdb67aeb09aa0c3b0c8cca7f Mon Sep 17 00:00:00 2001 From: Carina Paul <47103965+carina29@users.noreply.github.com> Date: Mon, 9 Jan 2023 12:36:58 +0200 Subject: [PATCH 080/166] #11240 - fixing the counter is UsersView (#11295) --- sormas-ui/src/main/java/de/symeda/sormas/ui/user/UsersView.java | 1 + 1 file changed, 1 insertion(+) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UsersView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UsersView.java index 2f3f24511c0..d3fceff67da 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UsersView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UsersView.java @@ -99,6 +99,7 @@ public UsersView() { gridLayout.addComponent(createActionsBar()); rowsCount = new RowCount(Strings.labelNumberOfUsers, grid.getDataSize()); + grid.addDataSizeChangeListener(e -> rowsCount.update(grid.getDataSize())); gridLayout.addComponent(rowsCount); gridLayout.addComponent(grid); From 43c79711234f6ece9412cd5b78a0b43623b59ff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=A9=20Strysewske?= Date: Mon, 9 Jan 2023 13:13:01 +0100 Subject: [PATCH 081/166] #7305 - Replaced interfaces --- .../sormas/backend/caze/CaseService.java | 8 +++-- ...oServiceWithUserFilterAndJurisdiction.java | 28 +++++++++++------ .../BaseLimitedChangeDateFilterProvider.java | 20 ------------ ...mentedLimitedChangeDateFilterProvider.java | 31 ------------------- .../backend/contact/ContactService.java | 9 ++++-- .../sormas/backend/event/EventService.java | 8 +++-- .../immunization/ImmunizationService.java | 9 ++++-- .../sormas/backend/task/TaskService.java | 9 ++++-- 8 files changed, 48 insertions(+), 74 deletions(-) delete mode 100644 sormas-backend/src/main/java/de/symeda/sormas/backend/common/BaseLimitedChangeDateFilterProvider.java delete mode 100644 sormas-backend/src/main/java/de/symeda/sormas/backend/common/ImplementedLimitedChangeDateFilterProvider.java 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 2fef14d09a3..905845acbdb 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 @@ -118,7 +118,6 @@ 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.common.ImplementedLimitedChangeDateFilterProvider; import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.contact.ContactJoins; import de.symeda.sormas.backend.contact.ContactQueryContext; @@ -181,7 +180,7 @@ @Stateless @LocalBean -public class CaseService extends AbstractCoreAdoService implements ImplementedLimitedChangeDateFilterProvider { +public class CaseService extends AbstractCoreAdoService { private static final Double SECONDS_30_DAYS = Long.valueOf(TimeUnit.DAYS.toSeconds(30L)).doubleValue(); @@ -2218,4 +2217,9 @@ private void selectIndexDtoFields(CaseQueryContext caseQueryContext) { CriteriaQuery cq = caseQueryContext.getQuery(); cq.multiselect(listQueryBuilder.getCaseIndexSelections(caseQueryContext.getRoot(), caseQueryContext)); } + + @Override + protected boolean hasLimitedChangeDateFilterImplementation() { + return true; + } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java index d1911cedb5b..282ec312cfb 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AdoServiceWithUserFilterAndJurisdiction.java @@ -1,5 +1,6 @@ package de.symeda.sormas.backend.common; +import java.sql.Timestamp; import java.util.Collections; import java.util.Date; import java.util.List; @@ -17,6 +18,7 @@ import de.symeda.sormas.api.RequestContextHolder; import de.symeda.sormas.api.feature.FeatureType; import de.symeda.sormas.api.feature.FeatureTypeProperty; +import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb; import de.symeda.sormas.backend.user.User; @@ -26,8 +28,7 @@ * @param * JPA entity managed by this Service. */ -public abstract class AdoServiceWithUserFilterAndJurisdiction extends BaseAdoService - implements BaseLimitedChangeDateFilterProvider { +public abstract class AdoServiceWithUserFilterAndJurisdiction extends BaseAdoService { public static final int NR_OF_LAST_PHONE_DIGITS_TO_SEARCH = 6; @EJB @@ -50,15 +51,22 @@ protected AdoServiceWithUserFilterAndJurisdiction(Class elementClass) { protected Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from) { if (hasLimitedChangeDateFilterImplementation()) { - return createLimitedChangeDateFilter( - cb, - from, - featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION), - featureConfigurationFacade - .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_PERIOD, Integer.class)); - } else { - return createEmptyLimitedChangeDateFilter(); + Integer maxChangeDatePeriod = featureConfigurationFacade + .getProperty(FeatureType.LIMITED_SYNCHRONIZATION, null, FeatureTypeProperty.MAX_CHANGE_DATE_PERIOD, Integer.class); + if (featureConfigurationFacade.isFeatureEnabled(FeatureType.LIMITED_SYNCHRONIZATION) + && maxChangeDatePeriod != null + && maxChangeDatePeriod >= 0) { + Date maxChangeDate = DateHelper.subtractDays(new Date(), maxChangeDatePeriod); + Timestamp timestamp = Timestamp.from(DateHelper.getStartOfDay(maxChangeDate).toInstant()); + return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(ADO.CHANGE_DATE), timestamp)); + } } + + return null; + } + + protected boolean hasLimitedChangeDateFilterImplementation() { + return false; } /** diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/BaseLimitedChangeDateFilterProvider.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/BaseLimitedChangeDateFilterProvider.java deleted file mode 100644 index de5e1207f89..00000000000 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/BaseLimitedChangeDateFilterProvider.java +++ /dev/null @@ -1,20 +0,0 @@ -package de.symeda.sormas.backend.common; - -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.From; -import javax.persistence.criteria.Predicate; - -public interface BaseLimitedChangeDateFilterProvider { - - default Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from, boolean featureEnabled, Integer maxChangeDatePeriod) { - return createEmptyLimitedChangeDateFilter(); - } - - default Predicate createEmptyLimitedChangeDateFilter() { - return null; - } - - default boolean hasLimitedChangeDateFilterImplementation() { - return false; - } -} diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/ImplementedLimitedChangeDateFilterProvider.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/ImplementedLimitedChangeDateFilterProvider.java deleted file mode 100644 index f5815aa3700..00000000000 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/ImplementedLimitedChangeDateFilterProvider.java +++ /dev/null @@ -1,31 +0,0 @@ -package de.symeda.sormas.backend.common; - -import java.sql.Timestamp; -import java.util.Date; - -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.From; -import javax.persistence.criteria.Predicate; - -import de.symeda.sormas.api.utils.DateHelper; - -public interface ImplementedLimitedChangeDateFilterProvider extends BaseLimitedChangeDateFilterProvider { - - @Override - default Predicate createLimitedChangeDateFilter(CriteriaBuilder cb, From from, boolean featureEnabled, Integer maxChangeDatePeriod) { - - if (featureEnabled && maxChangeDatePeriod != null && maxChangeDatePeriod >= 0) { - Date maxChangeDate = DateHelper.subtractDays(new Date(), maxChangeDatePeriod); - Timestamp timestamp = Timestamp.from(DateHelper.getStartOfDay(maxChangeDate).toInstant()); - return CriteriaBuilderHelper.and(cb, cb.greaterThanOrEqualTo(from.get(ADO.CHANGE_DATE), timestamp)); - } - - return null; - } - - @Override - default boolean hasLimitedChangeDateFilterImplementation() { - return true; - } - -} diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java index 60cd70c9f22..c34e88dd526 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactService.java @@ -96,7 +96,6 @@ 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.common.ImplementedLimitedChangeDateFilterProvider; import de.symeda.sormas.backend.common.JurisdictionFlagsService; import de.symeda.sormas.backend.contact.transformers.ContactListEntryDtoResultTransformer; import de.symeda.sormas.backend.disease.DiseaseConfigurationFacadeEjb.DiseaseConfigurationFacadeEjbLocal; @@ -139,8 +138,7 @@ @Stateless @LocalBean public class ContactService extends AbstractCoreAdoService - implements JurisdictionFlagsService, - ImplementedLimitedChangeDateFilterProvider { + implements JurisdictionFlagsService { @EJB private CaseService caseService; @@ -1814,4 +1812,9 @@ public long getContactCount(CaseReferenceDto caze) { return em.createQuery(cq).getSingleResult(); } + + @Override + protected boolean hasLimitedChangeDateFilterImplementation() { + return true; + } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java index a27dc082869..98707665e60 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventService.java @@ -74,7 +74,6 @@ 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.common.ImplementedLimitedChangeDateFilterProvider; import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.document.DocumentService; import de.symeda.sormas.backend.externalsurveillancetool.ExternalSurveillanceToolGatewayFacadeEjb; @@ -107,7 +106,7 @@ @Stateless @LocalBean -public class EventService extends AbstractCoreAdoService implements ImplementedLimitedChangeDateFilterProvider { +public class EventService extends AbstractCoreAdoService { @EJB private EventParticipantService eventParticipantService; @@ -1125,4 +1124,9 @@ public boolean hasAnyEventParticipantWithoutJurisdiction(String eventUuid) { return em.createQuery(cq).getSingleResult() > 0; } + + @Override + protected boolean hasLimitedChangeDateFilterImplementation() { + return true; + } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java index 2e774acb2cd..9a155dab52f 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationService.java @@ -54,7 +54,6 @@ import de.symeda.sormas.backend.common.ChangeDateBuilder; import de.symeda.sormas.backend.common.ChangeDateFilterBuilder; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; -import de.symeda.sormas.backend.common.ImplementedLimitedChangeDateFilterProvider; import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.immunization.entity.DirectoryImmunization; import de.symeda.sormas.backend.immunization.entity.Immunization; @@ -79,8 +78,7 @@ @Stateless @LocalBean -public class ImmunizationService extends AbstractCoreAdoService - implements ImplementedLimitedChangeDateFilterProvider { +public class ImmunizationService extends AbstractCoreAdoService { @EJB private PersonService personService; @@ -626,4 +624,9 @@ public Predicate createOwnershipPredicate(boolean withOwnership, From from cb.exists(sharesQuery)); } } + + @Override + protected boolean hasLimitedChangeDateFilterImplementation() { + return true; + } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java index 0642f19244d..8c67f839285 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java @@ -67,7 +67,6 @@ import de.symeda.sormas.backend.common.AbstractDomainObject; import de.symeda.sormas.backend.common.AdoServiceWithUserFilterAndJurisdiction; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; -import de.symeda.sormas.backend.common.ImplementedLimitedChangeDateFilterProvider; import de.symeda.sormas.backend.common.JurisdictionFlagsService; import de.symeda.sormas.backend.common.TaskCreationException; import de.symeda.sormas.backend.contact.Contact; @@ -91,8 +90,7 @@ @Stateless @LocalBean public class TaskService extends AdoServiceWithUserFilterAndJurisdiction - implements JurisdictionFlagsService, - ImplementedLimitedChangeDateFilterProvider { + implements JurisdictionFlagsService { @EJB private CaseService caseService; @@ -835,4 +833,9 @@ public EditPermissionType getEditPermissionType(Task task) { return EditPermissionType.ALLOWED; } + + @Override + protected boolean hasLimitedChangeDateFilterImplementation() { + return true; + } } From 88cbeb53f078304a85dc1297965ed7efce440f28 Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Mon, 9 Jan 2023 13:44:12 +0100 Subject: [PATCH 082/166] wrong test, ignored, need to fix by other team --- .../src/test/resources/features/sanity/web/User.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/User.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/User.feature index c7b5206cffb..6cfe7ac8ec9 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/User.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/User.feature @@ -335,7 +335,7 @@ Feature: Create user And I confirm user role deletion And I click on User Management tab from User Roles Page - @#10422 @env_main + @#10422 @env_main @ignore Scenario: Validate newly created user role is present in filtering options Given I log in as a Admin User And I click on the Users from navbar From 24513c1d22defa5e9b46445c49c6095dc775b93a Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Mon, 9 Jan 2023 14:46:54 +0100 Subject: [PATCH 083/166] fixes in xpath --- .../pages/application/configuration/CountriesTabPage.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java index 3b6c796cf98..5f87cfe9a22 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java @@ -36,8 +36,8 @@ public class CountriesTabPage { public static final By SUBCONTINENT_TABLE_VALUE = By.xpath("//table//tbody//tr[1]/td[4]"); public static final By COUNTRY_GRID_RESULTS_ROWS = By.cssSelector("[role=rowgroup] tr a"); public static final By NUMBER_OF_COUNTRIES = - By.xpath( - "//div[@class='v-label v-widget v-label-undef-w bold v-label-bold vspace-top-none v-label-vspace-top-none align-right v-label-align-right']"); + By.xpath( + "//div[@class='v-label v-widget bold v-label-bold vspace-top-none v-label-vspace-top-none align-right v-label-align-right v-label-undef-w']"); public static final By COUNTRIES_TABLE_DATA = By.tagName("td"); public static final By COUNTRIES_TABLE_ROW = By.cssSelector("div.v-grid-tablewrapper tbody tr"); public static final By COUNTRIES_NAME_TABLE_ROW = From 5eb30c0c0eeee7c7c6a16fdb5addf1ae88a6a850 Mon Sep 17 00:00:00 2001 From: Carina Paul Date: Tue, 10 Jan 2023 11:39:10 +0200 Subject: [PATCH 084/166] #11268 - do not disable/enable certain filters when entering/leaving bulk mode --- .../de/symeda/sormas/ui/caze/CaseFilterForm.java | 12 ------------ .../java/de/symeda/sormas/ui/caze/CasesView.java | 2 -- .../symeda/sormas/ui/contact/ContactsFilterForm.java | 5 ----- .../de/symeda/sormas/ui/contact/ContactsView.java | 2 -- 4 files changed, 21 deletions(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseFilterForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseFilterForm.java index e1051ff8f02..1ad1717e36d 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseFilterForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseFilterForm.java @@ -835,18 +835,6 @@ private void onApplyClick(EpiWeekAndDateFilterComponent weekAn } } - public void disableSearchAndReportingUser() { - getField(CaseCriteria.CASE_LIKE).setEnabled(false); - getField(CaseCriteria.EVENT_LIKE).setEnabled(false); - getField(CaseCriteria.REPORTING_USER_LIKE).setEnabled(false); - } - - public void enableSearchAndReportingUser() { - getField(CaseCriteria.CASE_LIKE).setEnabled(true); - getField(CaseCriteria.EVENT_LIKE).setEnabled(true); - getField(CaseCriteria.REPORTING_USER_LIKE).setEnabled(true); - } - @Override public void setValue(CaseCriteria newCriteria) throws ReadOnlyException, Converter.ConversionException { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasesView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasesView.java index 1a805c5ab3e..3ec845d756f 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasesView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasesView.java @@ -445,7 +445,6 @@ private void addCommonCasesOverviewToolbar() { ViewModelProviders.of(CasesView.class).get(CasesViewConfiguration.class).setInEagerMode(false); btnLeaveBulkEditMode.setVisible(false); btnEnterBulkEditMode.setVisible(true); - this.filterForm.enableSearchAndReportingUser(); navigateTo(criteria); }, ValoTheme.BUTTON_PRIMARY); btnLeaveBulkEditMode.setVisible(viewConfiguration.isInEagerMode()); @@ -550,7 +549,6 @@ private void enterBulkEditMode() { ViewModelProviders.of(CasesView.class).get(CasesViewConfiguration.class).setInEagerMode(true); btnEnterBulkEditMode.setVisible(false); btnLeaveBulkEditMode.setVisible(true); - filterForm.disableSearchAndReportingUser(); ((AbstractCaseGrid) grid).reload(); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsFilterForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsFilterForm.java index 021b65daef6..04ad294e83d 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsFilterForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsFilterForm.java @@ -555,11 +555,6 @@ private void onApplyClick(EpiWeekAndDateFilterComponent weekAnd } } - public void setSearchFieldEnabled(boolean enabled) { - this.getField(ContactCriteria.CONTACT_OR_CASE_LIKE).setEnabled(enabled); - this.getField(ContactCriteria.EVENT_LIKE).setEnabled(enabled); - } - private void populateContactResponsiblesForRegion(RegionReferenceDto regionReferenceDto) { List items = fetchContactResponsiblesByRegion(regionReferenceDto != null ? regionReferenceDto : currentUserDto().getRegion()); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsView.java index dffd58139b2..2cf4ebe698b 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactsView.java @@ -306,7 +306,6 @@ public ContactsView() { ViewModelProviders.of(getClass()).get(ContactsViewConfiguration.class).setInEagerMode(true); btnEnterBulkEditMode.setVisible(false); btnLeaveBulkEditMode.setVisible(true); - filterForm.setSearchFieldEnabled(false); ((AbstractContactGrid) grid).reload(); }); btnLeaveBulkEditMode.addClickListener(e -> { @@ -314,7 +313,6 @@ public ContactsView() { ViewModelProviders.of(getClass()).get(ContactsViewConfiguration.class).setInEagerMode(false); btnLeaveBulkEditMode.setVisible(false); btnEnterBulkEditMode.setVisible(true); - filterForm.setSearchFieldEnabled(true); navigateTo(criteria); }); } From 46ef805593c60250282422f2279e274da8fc5553 Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Tue, 10 Jan 2023 10:59:19 +0100 Subject: [PATCH 085/166] rerun=3 --- .../java/org/sormas/e2etests/runner/CucumberTestRunner.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/runner/CucumberTestRunner.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/runner/CucumberTestRunner.java index 499de598b1a..ca42a03a16a 100755 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/runner/CucumberTestRunner.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/runner/CucumberTestRunner.java @@ -29,7 +29,7 @@ runLevel = CourgetteRunLevel.SCENARIO, showTestOutput = true, rerunFailedScenarios = true, - rerunAttempts = 1, + rerunAttempts = 3, cucumberOptions = @CucumberOptions( features = "src/test/resources/features", From ec3b7f8f5914bcba84a0bdd213e545ac42b3f076 Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Tue, 10 Jan 2023 12:04:12 +0200 Subject: [PATCH 086/166] #11017 - Persons with incomplete home addresses from different jurisdictions can not be merged - changes after review --- .../backend/person/PersonFacadeEjb.java | 52 ++++++++++++++----- .../backend/person/PersonFacadeEjbTest.java | 8 +++ 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java index a9459ecf917..e5ac591c219 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java @@ -31,6 +31,7 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -120,6 +121,7 @@ import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.api.utils.SortProperty; import de.symeda.sormas.api.utils.ValidationRuntimeException; +import de.symeda.sormas.api.uuid.HasUuid; import de.symeda.sormas.api.vaccination.VaccinationDto; import de.symeda.sormas.backend.FacadeHelper; import de.symeda.sormas.backend.caze.Case; @@ -1869,26 +1871,34 @@ private void processPersonAddressMerge(PersonDto leadPersonDto, PersonDto otherP LocationDto otherAddress = otherPersonDto.getAddress(); otherAddress.setAddressType(PersonAddressType.OTHER_ADDRESS); otherAddress.setAddressTypeDetails(I18nProperties.getString(Strings.messagePersonMergedAddressDescription)); - leadPersonDto.addAddress(otherPersonDto.getAddress()); + leadPersonDto.addAddress(otherAddress); } else { DtoHelper.copyDtoValues(leadPersonDto.getAddress(), otherPersonDto.getAddress(), false); } } private boolean differentLocation(LocationDto firstAddress, LocationDto secondAddress) { - if (firstAddress.getCountry() != null && !firstAddress.getCountry().getUuid().equals(secondAddress.getCountry().getUuid())) { + + java.util.function.Predicate> differentInfrastructurePredicate = (Function function) -> { + return function.apply(firstAddress) != null + && function.apply(secondAddress) != null + && !DataHelper.equal(function.apply(firstAddress).getUuid(), function.apply(secondAddress).getUuid()); + + }; + + if (Boolean.TRUE.equals(differentInfrastructurePredicate.test(LocationDto::getCountry))) { return true; } - if (firstAddress.getRegion() != null && !firstAddress.getRegion().getUuid().equals(secondAddress.getRegion().getUuid())) { + if (Boolean.TRUE.equals(differentInfrastructurePredicate.test(LocationDto::getRegion))) { return true; } - if (firstAddress.getDistrict() != null && !firstAddress.getDistrict().getUuid().equals(secondAddress.getDistrict().getUuid())) { + if (Boolean.TRUE.equals(differentInfrastructurePredicate.test(LocationDto::getDistrict))) { return true; } - if (firstAddress.getCommunity() != null && !firstAddress.getCommunity().getUuid().equals(secondAddress.getCommunity().getUuid())) { + if (Boolean.TRUE.equals(differentInfrastructurePredicate.test(LocationDto::getCommunity))) { return true; } @@ -1900,21 +1910,37 @@ private boolean differentLocation(LocationDto firstAddress, LocationDto secondAd } } - if (firstAddress.getCity() != null && !firstAddress.getCity().equals(secondAddress.getCity())) { - return true; - } + boolean oneMatch = Boolean.FALSE; + boolean notNullValues = Boolean.FALSE; + boolean different = Boolean.FALSE; + List> addressValues = new ArrayList<>(); + addressValues.add(new Pair<>(firstAddress.getCity(), secondAddress.getCity())); + addressValues.add(new Pair<>(firstAddress.getPostalCode(), secondAddress.getPostalCode())); + addressValues.add(new Pair<>(firstAddress.getStreet(), secondAddress.getStreet())); + addressValues.add(new Pair<>(firstAddress.getHouseNumber(), secondAddress.getHouseNumber())); - if (firstAddress.getPostalCode() != null && !firstAddress.getPostalCode().equals(secondAddress.getPostalCode())) { - return true; + for (Pair addressTypePair : addressValues) { + if (addressTypePair.getElement0() != null && addressTypePair.getElement1() != null) { + if (!DataHelper.equal(addressTypePair.getElement0(), addressTypePair.getElement1())) { + different = Boolean.TRUE; + } else { + oneMatch = Boolean.TRUE; + } + } else { + if (addressTypePair.getElement1() != null) { + notNullValues = Boolean.TRUE; + } + } } - if (firstAddress.getStreet() != null && !firstAddress.getStreet().equals(secondAddress.getStreet())) { + if (different) { return true; } - if (firstAddress.getHouseNumber() != null && !firstAddress.getHouseNumber().equals(secondAddress.getHouseNumber())) { - return true; + if (notNullValues) { + return !oneMatch; } + return false; } diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/person/PersonFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/person/PersonFacadeEjbTest.java index 2f7e2755049..d9ebf8db71b 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/person/PersonFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/person/PersonFacadeEjbTest.java @@ -23,6 +23,9 @@ import java.util.Optional; import java.util.stream.Collectors; +import de.symeda.sormas.api.infrastructure.country.CountryDto; +import de.symeda.sormas.api.infrastructure.country.CountryReferenceDto; +import de.symeda.sormas.backend.infrastructure.country.Country; import org.junit.jupiter.api.Test; import de.symeda.sormas.api.CountryHelper; @@ -1046,6 +1049,11 @@ public void testMergePersonsSameMainAddress() { leadPersonAddress.setRegion(new RegionReferenceDto(rdcf1.region.getUuid())); leadPersonAddress.setDistrict(new DistrictReferenceDto(rdcf1.district.getUuid())); + Country country = creator.createCountry("Romania", "ROU", "642"); + getCountryService().doFlush(); + CountryReferenceDto countryReferenceDto = getCountryFacade().getReferenceByUuid(country.getUuid()); + leadPersonAddress.setCountry(countryReferenceDto); + LocationDto otherPersonAddress = otherPerson.getAddress(); otherPersonAddress.setRegion(new RegionReferenceDto(rdcf1.region.getUuid())); otherPersonAddress.setDistrict(new DistrictReferenceDto(rdcf1.district.getUuid())); From 4ef68e430d49b012a7c9aa9b4e952745b7a12c8f Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Tue, 10 Jan 2023 12:07:24 +0200 Subject: [PATCH 087/166] #11017 - Persons with incomplete home addresses from different jurisdictions can not be merged - changes after review --- .../src/main/java/de/symeda/sormas/api/person/PersonFacade.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/person/PersonFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/person/PersonFacade.java index 9e53baf4651..c74b44060fe 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/person/PersonFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/person/PersonFacade.java @@ -82,7 +82,7 @@ public interface PersonFacade extends BaseFacade Date: Tue, 10 Jan 2023 12:13:04 +0200 Subject: [PATCH 088/166] #11017 - Persons with incomplete home addresses from different jurisdictions can not be merged - changes after review --- .../java/de/symeda/sormas/ui/person/PersonController.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonController.java index 6a65e3770b6..1c8f9963fb9 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonController.java @@ -185,11 +185,7 @@ private void mergePersons(PersonGrid personGrid, List personInde 800, confirm -> { if (Boolean.TRUE.equals(confirm)) { - try { - FacadeProvider.getPersonFacade().mergePerson(leadPerson.getUuid(), otherPerson.getUuid(), mergeProperties); - } catch (CloneNotSupportedException e) { - e.printStackTrace(); - } + FacadeProvider.getPersonFacade().mergePerson(leadPerson.getUuid(), otherPerson.getUuid(), mergeProperties); popupWindow.close(); SormasUI.refreshView(); } From 2a9364ed56bf46e3796f42de907583d8831d2c6b Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Tue, 10 Jan 2023 12:22:28 +0200 Subject: [PATCH 089/166] #11017 - Persons with incomplete home addresses from different jurisdictions can not be merged - changes after review --- .../de/symeda/sormas/backend/person/PersonFacadeEjb.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java index e5ac591c219..2465992e32e 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java @@ -1912,7 +1912,6 @@ private boolean differentLocation(LocationDto firstAddress, LocationDto secondAd boolean oneMatch = Boolean.FALSE; boolean notNullValues = Boolean.FALSE; - boolean different = Boolean.FALSE; List> addressValues = new ArrayList<>(); addressValues.add(new Pair<>(firstAddress.getCity(), secondAddress.getCity())); addressValues.add(new Pair<>(firstAddress.getPostalCode(), secondAddress.getPostalCode())); @@ -1922,7 +1921,7 @@ private boolean differentLocation(LocationDto firstAddress, LocationDto secondAd for (Pair addressTypePair : addressValues) { if (addressTypePair.getElement0() != null && addressTypePair.getElement1() != null) { if (!DataHelper.equal(addressTypePair.getElement0(), addressTypePair.getElement1())) { - different = Boolean.TRUE; + return true; } else { oneMatch = Boolean.TRUE; } @@ -1933,10 +1932,6 @@ private boolean differentLocation(LocationDto firstAddress, LocationDto secondAd } } - if (different) { - return true; - } - if (notNullValues) { return !oneMatch; } From 7bc63dc53748749787367413fdc8c0537913536c Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Tue, 10 Jan 2023 12:49:53 +0200 Subject: [PATCH 090/166] #11017 - Persons with incomplete home addresses from different jurisdictions can not be merged - changes after review --- .../de/symeda/sormas/backend/person/PersonFacadeEjb.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java index 2465992e32e..bad86fa05e0 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java @@ -1919,7 +1919,10 @@ private boolean differentLocation(LocationDto firstAddress, LocationDto secondAd addressValues.add(new Pair<>(firstAddress.getHouseNumber(), secondAddress.getHouseNumber())); for (Pair addressTypePair : addressValues) { - if (addressTypePair.getElement0() != null && addressTypePair.getElement1() != null) { + if (addressTypePair.getElement0() != null + && !addressTypePair.getElement0().isEmpty() + && addressTypePair.getElement1() != null + && !addressTypePair.getElement1().isEmpty()) { if (!DataHelper.equal(addressTypePair.getElement0(), addressTypePair.getElement1())) { return true; } else { From 65bdc3f3794b564bff21d11237bbfab0302ebdc7 Mon Sep 17 00:00:00 2001 From: Carina Paul Date: Tue, 10 Jan 2023 13:35:43 +0200 Subject: [PATCH 091/166] #11226 - set assignedUserBy in bulk edit mode --- .../src/main/java/de/symeda/sormas/ui/task/TaskController.java | 1 + 1 file changed, 1 insertion(+) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskController.java index 08d3d1cc477..aa2ed53ebe2 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskController.java @@ -232,6 +232,7 @@ public void showBulkTaskDataEditComponent(Collection sel } if (form.getAssigneeCheckbox().getValue()) { dto.setAssigneeUser(updatedBulkEditData.getTaskAssignee()); + dto.setAssignedByUser(UserProvider.getCurrent().getUserReference()); } if (form.getTaskStatusCheckbox().getValue()) { dto.setTaskStatus(updatedBulkEditData.getTaskStatus()); From 0b6c50179518baaef16e8417378744f9f10b7a67 Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Tue, 10 Jan 2023 15:40:56 +0100 Subject: [PATCH 092/166] fix --- .../application/cases/CaseDirectorySteps.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDirectorySteps.java index 140d2cdda7f..89fa1005e00 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDirectorySteps.java @@ -73,6 +73,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.text.DateFormatSymbols; import java.time.LocalDate; import java.time.ZoneId; import java.time.format.DateTimeFormatter; @@ -988,17 +989,18 @@ public CaseDirectorySteps( And( "I apply Month filter different than Person has on Case directory page", - () -> - webDriverHelpers.selectFromCombobox( - CASE_MONTH_FILTER, - getRandomNumberForBirthDateDifferentThanCreated( - apiState.getLastCreatedPerson().getBirthdateMM(), 1, 12) - .toString())); + () -> { + DateFormatSymbols dFs = new DateFormatSymbols(); + String month = dFs.getMonths()[apiState.getLastCreatedPerson().getBirthdateMM() - 2]; + webDriverHelpers.selectFromCombobox(CASE_MONTH_FILTER, month); + }); And( "I apply Month filter of last api created Person on Case directory page", - () -> - webDriverHelpers.selectFromCombobox( - CASE_MONTH_FILTER, apiState.getLastCreatedPerson().getBirthdateMM().toString())); + () -> { + DateFormatSymbols dFs = new DateFormatSymbols(); + String month = dFs.getMonths()[apiState.getLastCreatedPerson().getBirthdateMM() - 1]; + webDriverHelpers.selectFromCombobox(CASE_MONTH_FILTER, month); + }); And( "I apply Day filter different than Person has on Case directory page", () -> From 1eba679a8bc32e3f210ef279b91cd544d686e922 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Tue, 10 Jan 2023 16:07:48 +0100 Subject: [PATCH 093/166] fix - one additional fields added to check in Case directory detail table --- .../steps/web/application/cases/CaseDetailedTableViewSteps.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDetailedTableViewSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDetailedTableViewSteps.java index 550d7541706..04db6092d2f 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDetailedTableViewSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDetailedTableViewSteps.java @@ -56,7 +56,7 @@ public CaseDetailedTableViewSteps( List> tableRowsData = getTableRowsData(); Map detailedCaseDTableRow = tableRowsData.get(0); softly.assertEquals( - detailedCaseDTableRow.size(), 39, "Case table rows count is not correct"); + detailedCaseDTableRow.size(), 40, "Case table rows count is not correct"); softly.assertTrue( detailedCaseDTableRow From 98d459cfb0e0788834bed6762c755dd45ccad0f7 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Tue, 10 Jan 2023 16:09:45 +0100 Subject: [PATCH 094/166] tag added just to run this test on Jenkins --- .../src/test/resources/features/sanity/web/CaseViews.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/CaseViews.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/CaseViews.feature index 5830f2dad46..3591234f91d 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/CaseViews.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/CaseViews.feature @@ -1,7 +1,7 @@ @UI @Sanity @CaseView Feature: Case view tests - @env_main + @env_main @additionalField Scenario: Create a new Case and check details in Detailed view table Given API: I create a new person Then API: I check that POST call body is "OK" From a90e003693a6248a0082f7473bbdad3088579d39 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Tue, 10 Jan 2023 16:16:48 +0100 Subject: [PATCH 095/166] tag has been removed --- .../src/test/resources/features/sanity/web/CaseViews.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/CaseViews.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/CaseViews.feature index 3591234f91d..5830f2dad46 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/CaseViews.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/CaseViews.feature @@ -1,7 +1,7 @@ @UI @Sanity @CaseView Feature: Case view tests - @env_main @additionalField + @env_main Scenario: Create a new Case and check details in Detailed view table Given API: I create a new person Then API: I check that POST call body is "OK" From 01a71742fa75fa72edeeb9e641732734f40104f7 Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Tue, 10 Jan 2023 16:26:48 +0100 Subject: [PATCH 096/166] fix --- .../web/application/cases/CaseDirectorySteps.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDirectorySteps.java index 89fa1005e00..bd8182d0349 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/CaseDirectorySteps.java @@ -80,6 +80,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; @@ -938,7 +939,9 @@ public CaseDirectorySteps( And( "I apply Month filter of Person attached to last created UI Case on Case directory page", () -> { - String month = Integer.toString(CreateNewCaseSteps.caze.getDateOfBirth().getMonthValue()); + DateFormatSymbols dFs = new DateFormatSymbols(Locale.GERMAN); + String month = + dFs.getMonths()[CreateNewCaseSteps.caze.getDateOfBirth().getMonthValue() - 1]; webDriverHelpers.selectFromCombobox(CASE_MONTH_FILTER, month); }); And( @@ -959,11 +962,10 @@ public CaseDirectorySteps( And( "I apply Month filter other than Person attached has to last created UI Case on Case directory page", () -> { - webDriverHelpers.selectFromCombobox( - CASE_MONTH_FILTER, - getRandomNumberForBirthDateDifferentThanCreated( - CreateNewCaseSteps.caze.getDateOfBirth().getMonthValue(), 1, 12) - .toString()); + DateFormatSymbols dFs = new DateFormatSymbols(Locale.GERMAN); + String month = + dFs.getMonths()[CreateNewCaseSteps.caze.getDateOfBirth().getMonthValue() - 2]; + webDriverHelpers.selectFromCombobox(CASE_MONTH_FILTER, month); }); And( "I apply Day filter other than Person attached has to last created UI Case on Case directory page", From 3a113bb83351c7b178f2de8687c70a2dcae0711a Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Tue, 10 Jan 2023 18:03:16 +0200 Subject: [PATCH 097/166] #11017 - Persons with incomplete home addresses from different jurisdictions can not be merged - changes after review --- .../backend/location/LocationFacadeEjb.java | 70 +++++++++++++++++++ .../backend/person/PersonFacadeEjb.java | 69 +----------------- 2 files changed, 71 insertions(+), 68 deletions(-) diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/location/LocationFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/location/LocationFacadeEjb.java index dd8c44dc99e..c29f2737dd9 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/location/LocationFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/location/LocationFacadeEjb.java @@ -17,12 +17,20 @@ *******************************************************************************/ package de.symeda.sormas.backend.location; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; + import javax.ejb.EJB; import javax.ejb.LocalBean; import javax.ejb.Stateless; +import org.apache.commons.lang3.StringUtils; + import de.symeda.sormas.api.location.LocationDto; import de.symeda.sormas.api.location.LocationFacade; +import de.symeda.sormas.api.utils.DataHelper; +import de.symeda.sormas.api.uuid.HasUuid; import de.symeda.sormas.backend.infrastructure.community.CommunityFacadeEjb; import de.symeda.sormas.backend.infrastructure.community.CommunityService; import de.symeda.sormas.backend.infrastructure.continent.ContinentFacadeEjb; @@ -31,6 +39,7 @@ import de.symeda.sormas.backend.infrastructure.country.CountryService; import de.symeda.sormas.backend.infrastructure.district.DistrictFacadeEjb; import de.symeda.sormas.backend.infrastructure.district.DistrictService; +import de.symeda.sormas.backend.infrastructure.facility.Facility; import de.symeda.sormas.backend.infrastructure.facility.FacilityFacadeEjb; import de.symeda.sormas.backend.infrastructure.facility.FacilityService; import de.symeda.sormas.backend.infrastructure.region.RegionFacadeEjb; @@ -138,6 +147,67 @@ public static LocationDto toDto(Location source) { return target; } + public boolean areDifferentLocation(LocationDto firstAddress, LocationDto secondAddress) { + + java.util.function.Predicate> differentInfrastructurePredicate = (Function function) -> { + return function.apply(firstAddress) != null + && function.apply(secondAddress) != null + && !DataHelper.equal(function.apply(firstAddress).getUuid(), function.apply(secondAddress).getUuid()); + + }; + + if (Boolean.TRUE.equals(differentInfrastructurePredicate.test(LocationDto::getCountry))) { + return true; + } + + if (Boolean.TRUE.equals(differentInfrastructurePredicate.test(LocationDto::getRegion))) { + return true; + } + + if (Boolean.TRUE.equals(differentInfrastructurePredicate.test(LocationDto::getDistrict))) { + return true; + } + + if (Boolean.TRUE.equals(differentInfrastructurePredicate.test(LocationDto::getCommunity))) { + return true; + } + + if (firstAddress.getFacility() != null) { + Facility firstAddressFacilityDto = facilityService.getByUuid(firstAddress.getFacility().getUuid()); + if (secondAddress.getCommunity() != null + && firstAddressFacilityDto.getCommunity() != null + && !firstAddressFacilityDto.getCommunity().getUuid().equals(secondAddress.getCommunity().getUuid())) { + return true; + } + } + + boolean oneMatch = Boolean.FALSE; + boolean secondLocationHasAddressValues = Boolean.FALSE; + List> addressValues = new ArrayList<>(); + addressValues.add(new DataHelper.Pair<>(firstAddress.getCity(), secondAddress.getCity())); + addressValues.add(new DataHelper.Pair<>(firstAddress.getPostalCode(), secondAddress.getPostalCode())); + addressValues.add(new DataHelper.Pair<>(firstAddress.getStreet(), secondAddress.getStreet())); + addressValues.add(new DataHelper.Pair<>(firstAddress.getHouseNumber(), secondAddress.getHouseNumber())); + + for (DataHelper.Pair addressTypePair : addressValues) { + if (StringUtils.isNotBlank(addressTypePair.getElement0()) && StringUtils.isNotBlank(addressTypePair.getElement1())) { + if (!DataHelper.equal(addressTypePair.getElement0(), addressTypePair.getElement1())) { + return true; + } else { + oneMatch = Boolean.TRUE; + } + } else if (addressTypePair.getElement1() != null) { + secondLocationHasAddressValues = Boolean.TRUE; + } + } + + if (secondLocationHasAddressValues) { + return !oneMatch; + } + + return false; + } + @LocalBean @Stateless public static class LocationFacadeEjbLocal extends LocationFacadeEjb { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java index bad86fa05e0..420d9f53de3 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java @@ -31,7 +31,6 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; -import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -121,7 +120,6 @@ import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.api.utils.SortProperty; import de.symeda.sormas.api.utils.ValidationRuntimeException; -import de.symeda.sormas.api.uuid.HasUuid; import de.symeda.sormas.api.vaccination.VaccinationDto; import de.symeda.sormas.backend.FacadeHelper; import de.symeda.sormas.backend.caze.Case; @@ -1867,7 +1865,7 @@ public void mergePerson(String leadPersonUuid, String otherPersonUuid, boolean m } private void processPersonAddressMerge(PersonDto leadPersonDto, PersonDto otherPersonDto) { - if (differentLocation(leadPersonDto.getAddress(), otherPersonDto.getAddress())) { + if (locationFacade.areDifferentLocation(leadPersonDto.getAddress(), otherPersonDto.getAddress())) { LocationDto otherAddress = otherPersonDto.getAddress(); otherAddress.setAddressType(PersonAddressType.OTHER_ADDRESS); otherAddress.setAddressTypeDetails(I18nProperties.getString(Strings.messagePersonMergedAddressDescription)); @@ -1877,71 +1875,6 @@ private void processPersonAddressMerge(PersonDto leadPersonDto, PersonDto otherP } } - private boolean differentLocation(LocationDto firstAddress, LocationDto secondAddress) { - - java.util.function.Predicate> differentInfrastructurePredicate = (Function function) -> { - return function.apply(firstAddress) != null - && function.apply(secondAddress) != null - && !DataHelper.equal(function.apply(firstAddress).getUuid(), function.apply(secondAddress).getUuid()); - - }; - - if (Boolean.TRUE.equals(differentInfrastructurePredicate.test(LocationDto::getCountry))) { - return true; - } - - if (Boolean.TRUE.equals(differentInfrastructurePredicate.test(LocationDto::getRegion))) { - return true; - } - - if (Boolean.TRUE.equals(differentInfrastructurePredicate.test(LocationDto::getDistrict))) { - return true; - } - - if (Boolean.TRUE.equals(differentInfrastructurePredicate.test(LocationDto::getCommunity))) { - return true; - } - - if (firstAddress.getFacility() != null) { - FacilityDto firstAddressFacilityDto = facilityFacade.getByUuid(firstAddress.getFacility().getUuid()); - if (secondAddress.getCommunity() != null - && !firstAddressFacilityDto.getCommunity().getUuid().equals(secondAddress.getCommunity().getUuid())) { - return true; - } - } - - boolean oneMatch = Boolean.FALSE; - boolean notNullValues = Boolean.FALSE; - List> addressValues = new ArrayList<>(); - addressValues.add(new Pair<>(firstAddress.getCity(), secondAddress.getCity())); - addressValues.add(new Pair<>(firstAddress.getPostalCode(), secondAddress.getPostalCode())); - addressValues.add(new Pair<>(firstAddress.getStreet(), secondAddress.getStreet())); - addressValues.add(new Pair<>(firstAddress.getHouseNumber(), secondAddress.getHouseNumber())); - - for (Pair addressTypePair : addressValues) { - if (addressTypePair.getElement0() != null - && !addressTypePair.getElement0().isEmpty() - && addressTypePair.getElement1() != null - && !addressTypePair.getElement1().isEmpty()) { - if (!DataHelper.equal(addressTypePair.getElement0(), addressTypePair.getElement1())) { - return true; - } else { - oneMatch = Boolean.TRUE; - } - } else { - if (addressTypePair.getElement1() != null) { - notNullValues = Boolean.TRUE; - } - } - } - - if (notNullValues) { - return !oneMatch; - } - - return false; - } - @Override public boolean isPersonSimilar(PersonSimilarityCriteria criteria, String personUuid) { return service.isPersonSimilar(criteria, personUuid); From ece9069f38f76260184ac3717a107f01328e3c33 Mon Sep 17 00:00:00 2001 From: Levente Gal Date: Tue, 10 Jan 2023 21:48:11 +0200 Subject: [PATCH 098/166] #11293 [Cases] 'Point of entry name and description' header is displayed on the case page even it is not used - don't show point of entry name & details when it's pseudonymized --- .../src/main/java/de/symeda/sormas/ui/caze/CaseDataForm.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataForm.java index c5b2ce32483..d57cd9cabf9 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataForm.java @@ -423,7 +423,7 @@ protected void addFields() { if (FacadeProvider.getExternalSurveillanceToolFacade().isFeatureEnabled()) { CheckBox dontShareCheckbox = addField(CaseDataDto.DONT_SHARE_WITH_REPORTING_TOOL, CheckBox.class); CaseFormHelper.addDontShareWithReportingTool(getContent(), () -> dontShareCheckbox, DONT_SHARE_WARNING_LOC); - if(FacadeProvider.getExternalShareInfoFacade().isSharedCase(this.caseUuid)){ + if (FacadeProvider.getExternalShareInfoFacade().isSharedCase(this.caseUuid)) { dontShareCheckbox.setEnabled(false); dontShareCheckbox.setDescription(I18nProperties.getString(Strings.infoDontShareCheckboxAlreadyShared)); } @@ -1311,6 +1311,9 @@ protected void addFields() { setVisible(getValue().getPointOfEntry().isOtherPointOfEntry(), CaseDataDto.POINT_OF_ENTRY_DETAILS); btnReferFromPointOfEntry .setVisible(UserProvider.getCurrent().hasUserRight(UserRight.CASE_REFER_FROM_POE) && getValue().getHealthFacility() == null); + } else if (!isEditableAllowed(CaseDataDto.POINT_OF_ENTRY)) { + setVisible(false, CaseDataDto.POINT_OF_ENTRY_DETAILS); + btnReferFromPointOfEntry.setVisible(false); } if (getValue().getHealthFacility() == null) { From 4d5119489a9e6e3de4312cde9a7ea9efd25306eb Mon Sep 17 00:00:00 2001 From: Levente Gal <62599627+leventegal-she@users.noreply.github.com> Date: Tue, 10 Jan 2023 21:50:56 +0200 Subject: [PATCH 099/166] #11192 Can't send Exposures via REST - fixed NullPointer exception when saving exposure without location (#11311) * #11192 Can't send Exposures via REST - fixed NullPointer exception when saving exposure without location Co-authored-by: Levente Gal --- .../sormas/api/utils/pseudonymization/DtoPseudonymizer.java | 2 +- .../backend/clinicalcourse/ClinicalVisitFacadeEjb.java | 2 +- .../de/symeda/sormas/backend/contact/ContactFacadeEjb.java | 2 +- .../de/symeda/sormas/backend/epidata/EpiDataFacadeEjb.java | 5 +++-- .../java/de/symeda/sormas/backend/event/EventFacadeEjb.java | 2 +- .../de/symeda/sormas/backend/person/PersonFacadeEjb.java | 2 +- .../java/de/symeda/sormas/backend/user/UserFacadeEjb.java | 2 +- .../java/de/symeda/sormas/backend/visit/VisitFacadeEjb.java | 2 +- 8 files changed, 10 insertions(+), 9 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/utils/pseudonymization/DtoPseudonymizer.java b/sormas-api/src/main/java/de/symeda/sormas/api/utils/pseudonymization/DtoPseudonymizer.java index 647e61414b6..39b21d21e14 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/utils/pseudonymization/DtoPseudonymizer.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/utils/pseudonymization/DtoPseudonymizer.java @@ -105,7 +105,7 @@ public boolean isAccessible(Class type, String fieldName, boolean isI } public void restorePseudonymizedValues(Class type, DTO dto, DTO originalDto, boolean isInJurisdiction) { - if (originalDto == null) { + if (dto == null || originalDto == null) { return; } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitFacadeEjb.java index 1b3a90f2ce9..c1fd4480730 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitFacadeEjb.java @@ -436,7 +436,7 @@ public ClinicalVisit fillOrBuildEntity(@NotNull ClinicalVisitDto source, Clinica target = DtoHelper.fillOrBuildEntity(source, target, ClinicalVisit::new, checkChangeDate); if (targetWasNull) { - target.getSymptoms().setUuid(source.getSymptoms().getUuid()); + FacadeHelper.setUuidIfDtoExists(target.getSymptoms(), source.getSymptoms()); } target.setClinicalCourse(clinicalCourseService.getByReferenceDto(source.getClinicalCourse())); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactFacadeEjb.java index b535085859d..59da40fead9 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactFacadeEjb.java @@ -1408,7 +1408,7 @@ public Contact fillOrBuildEntity(@NotNull ContactDto source, Contact target, boo target = DtoHelper.fillOrBuildEntity(source, target, Contact::new, checkChangeDate); if (targetWasNull) { - target.getEpiData().setUuid(source.getEpiData().getUuid()); + FacadeHelper.setUuidIfDtoExists(target.getEpiData(), source.getEpiData()); } target.setCaze(caseService.getByReferenceDto(source.getCaze())); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/epidata/EpiDataFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/epidata/EpiDataFacadeEjb.java index dd624376dbd..fb0f47384f2 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/epidata/EpiDataFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/epidata/EpiDataFacadeEjb.java @@ -32,6 +32,7 @@ import de.symeda.sormas.api.epidata.EpiDataFacade; import de.symeda.sormas.api.exposure.ExposureDto; import de.symeda.sormas.api.utils.DataHelper; +import de.symeda.sormas.backend.FacadeHelper; import de.symeda.sormas.backend.activityascase.ActivityAsCase; import de.symeda.sormas.backend.activityascase.ActivityAsCaseService; import de.symeda.sormas.backend.contact.ContactFacadeEjb; @@ -112,7 +113,7 @@ public Exposure fillOrBuildExposureEntity(ExposureDto source, Exposure target, b target = DtoHelper.fillOrBuildEntity(source, target, Exposure::new, checkChangeDate); if (targetWasNull) { - target.getLocation().setUuid(source.getLocation().getUuid()); + FacadeHelper.setUuidIfDtoExists(target.getLocation(), source.getLocation()); } target.setAnimalCondition(source.getAnimalCondition()); @@ -181,7 +182,7 @@ public ActivityAsCase fillOrBuildActivityAsCaseEntity(ActivityAsCaseDto source, target = DtoHelper.fillOrBuildEntity(source, target, ActivityAsCase::new, checkChangeDate); if (targetWasNull) { - target.getLocation().setUuid(source.getLocation().getUuid()); + FacadeHelper.setUuidIfDtoExists(target.getLocation(), source.getLocation()); } target.setReportingUser(userService.getByReferenceDto(source.getReportingUser())); 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 4357e20aa64..de6267a4239 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 @@ -1235,7 +1235,7 @@ public Event fillOrBuildEntity(@NotNull EventDto source, Event target, boolean c target = DtoHelper.fillOrBuildEntity(source, target, Event::new, checkChangeDate); if (targetWasNull) { - target.getEventLocation().setUuid(source.getEventLocation().getUuid()); + FacadeHelper.setUuidIfDtoExists(target.getEventLocation(), source.getEventLocation()); } target.setEventStatus(source.getEventStatus()); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java index 0fade1039c5..c31c36c0fa3 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java @@ -1645,7 +1645,7 @@ public Person fillOrBuildEntity(@NotNull PersonDto source, Person target, boolea target = DtoHelper.fillOrBuildEntity(source, target, service::createPerson, checkChangeDate); if (targetWasNull) { - target.getAddress().setUuid(source.getAddress().getUuid()); + FacadeHelper.setUuidIfDtoExists(target.getAddress(), source.getAddress()); } target.setFirstName(source.getFirstName()); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserFacadeEjb.java index 7b244e0d70a..d536a45a19f 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserFacadeEjb.java @@ -738,7 +738,7 @@ private User fillOrBuildEntity(UserDto source, User target, boolean checkChangeD target = DtoHelper.fillOrBuildEntity(source, target, userService::createUser, checkChangeDate); if (targetWasNull) { - target.getAddress().setUuid(source.getAddress().getUuid()); + FacadeHelper.setUuidIfDtoExists(target.getAddress(), source.getAddress()); } target.setActive(source.isActive()); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitFacadeEjb.java index c854d206764..b4a0887fac4 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitFacadeEjb.java @@ -515,7 +515,7 @@ public Visit fillOrBuildEntity(@NotNull VisitDto source, Visit target, boolean c target = DtoHelper.fillOrBuildEntity(source, target, Visit::new, checkChangeDate); if (targetWasNull) { - target.getSymptoms().setUuid(source.getSymptoms().getUuid()); + FacadeHelper.setUuidIfDtoExists(target.getSymptoms(), source.getSymptoms()); } target.setDisease(source.getDisease()); From 58ddec978d941a6a6d2de0954c6a8c54ff27b033 Mon Sep 17 00:00:00 2001 From: Christopher Riedel Date: Wed, 11 Jan 2023 08:50:44 +0100 Subject: [PATCH 100/166] #10484: Added validation (#11294) * #10484: Added validation * #10484: fixed review findings --- .../de/symeda/sormas/api/caze/CaseLogic.java | 4 ++ .../sormas/api/contact/ContactLogic.java | 4 ++ .../symeda/sormas/api/visit/VisitFacade.java | 7 ++- .../symeda/sormas/api/visit/VisitLogic.java | 21 +++++++ .../sormas/backend/visit/VisitFacadeEjb.java | 34 ++++++++-- .../sormas/ui/configuration/DevModeView.java | 63 ++++++++++++------- .../sormas/ui/visit/VisitController.java | 44 ++++++++++--- .../symeda/sormas/ui/visit/VisitEditForm.java | 2 +- 8 files changed, 143 insertions(+), 36 deletions(-) create mode 100644 sormas-api/src/main/java/de/symeda/sormas/api/visit/VisitLogic.java diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseLogic.java b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseLogic.java index a6b67530550..cfc659c40ab 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseLogic.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseLogic.java @@ -87,6 +87,10 @@ public static FollowUpPeriodDto getFollowUpStartDate(Date onsetDate, Date report return FollowUpLogic.getFollowUpStartDate(reportDate, earliestSampleDate); } + public static Date getEndDate(CaseDataDto caseDto) { + return getEndDate(caseDto.getSymptoms().getOnsetDate(), caseDto.getReportDate(), caseDto.getFollowUpUntil()); + } + public static Date getEndDate(Date onsetDate, Date reportDate, Date followUpUntil) { return followUpUntil != null ? followUpUntil : onsetDate != null ? onsetDate : reportDate; } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactLogic.java b/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactLogic.java index 9df20f4da28..25271fb2167 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactLogic.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactLogic.java @@ -61,6 +61,10 @@ public static FollowUpPeriodDto getFollowUpStartDate(Date lastContactDate, Date return FollowUpLogic.getFollowUpStartDate(reportDate, earliestSampleDate); } + public static Date getEndDate(ContactDto contactDto) { + return getEndDate(contactDto.getLastContactDate(), contactDto.getReportDateTime(), contactDto.getFollowUpUntil()); + } + public static Date getEndDate(Date lastContactDate, Date reportDate, Date followUpUntil) { return followUpUntil != null ? followUpUntil : lastContactDate != null ? lastContactDate : reportDate; } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/visit/VisitFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/visit/VisitFacade.java index 19274108768..c91eb383bfa 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/visit/VisitFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/visit/VisitFacade.java @@ -39,9 +39,14 @@ public interface VisitFacade { VisitDto getVisitByUuid(String uuid); + /** + * Only allowed to use for ExternalVisits, merging and test puroses + */ VisitDto saveVisit(@Valid VisitDto dto); - void validate(VisitDto dto); + VisitDto saveVisit(@Valid VisitDto dto, Date allowedStartDate, Date allowedEndDate); + + void validate(VisitDto dto, Date allowedStartDate, Date allowedEndDate); ExternalVisitDto saveExternalVisit(@Valid ExternalVisitDto dto); diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/visit/VisitLogic.java b/sormas-api/src/main/java/de/symeda/sormas/api/visit/VisitLogic.java new file mode 100644 index 00000000000..5db1beedaf6 --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/visit/VisitLogic.java @@ -0,0 +1,21 @@ +package de.symeda.sormas.api.visit; + +import java.util.Date; + +import de.symeda.sormas.api.followup.FollowUpLogic; +import de.symeda.sormas.api.utils.DateHelper; + +public final class VisitLogic { + + private VisitLogic() { + // Hide Utility Class Constructor + } + + public static Date getAllowedEndDate(Date endDate) { + return DateHelper.addDays(DateHelper.getEndOfDay(endDate), FollowUpLogic.ALLOWED_DATE_OFFSET); + } + + public static Date getAllowedStartDate(Date startDate) { + return DateHelper.subtractDays(DateHelper.getStartOfDay(startDate), FollowUpLogic.ALLOWED_DATE_OFFSET); + } +} diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitFacadeEjb.java index b4a0887fac4..74703d732af 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitFacadeEjb.java @@ -68,6 +68,7 @@ import de.symeda.sormas.api.user.UserReferenceDto; import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.api.utils.DataHelper; +import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.api.utils.SortProperty; import de.symeda.sormas.api.utils.ValidationRuntimeException; import de.symeda.sormas.api.visit.ExternalVisitDto; @@ -221,17 +222,28 @@ public VisitDto getVisitByUuid(String uuid) { return convertToDto(visitService.getByUuid(uuid), createPseudonymizer()); } + /** + * Only allowed to use for ExternalVisits, merging and test puroses + */ @Override @RightsAllowed({ UserRight._VISIT_CREATE, UserRight._VISIT_EDIT }) public VisitDto saveVisit(@Valid VisitDto dto) { + return saveVisit(dto, null, null); + } + + @Override + @RightsAllowed({ + UserRight._VISIT_CREATE, + UserRight._VISIT_EDIT }) + public VisitDto saveVisit(@Valid VisitDto dto, Date allowedStartDate, Date allowedEndDate) { final String visitUuid = dto.getUuid(); final Visit existingVisit = visitUuid != null ? visitService.getByUuid(visitUuid) : null; FacadeHelper.checkCreateAndEditRights(existingVisit, userService, UserRight.VISIT_CREATE, UserRight.VISIT_EDIT); - return doSaveVisit(dto, existingVisit); + return doSaveVisit(dto, existingVisit, allowedStartDate, allowedEndDate); } @Override @@ -254,7 +266,7 @@ public ExternalVisitDto saveExternalVisit(@Valid final ExternalVisitDto dto) { dto.getReportLatLonAccuracy(), VisitOrigin.EXTERNAL_JOURNAL); - doSaveVisit(visitDto, null); + doSaveVisit(visitDto, null, null, null); return ExternalVisitDto.build( personUuid, @@ -268,12 +280,12 @@ public ExternalVisitDto saveExternalVisit(@Valid final ExternalVisitDto dto) { visitDto.getReportLatLonAccuracy()); } - private VisitDto doSaveVisit(@Valid VisitDto dto, Visit existingVisit) { + private VisitDto doSaveVisit(@Valid VisitDto dto, Visit existingVisit, Date allowedStartDate, Date allowedEndDate) { final VisitDto existingDto = toDto(existingVisit); restorePseudonymizedDto(dto, existingVisit, existingDto); - this.validate(dto); + this.validate(dto, allowedStartDate, allowedEndDate); if (dto.getVisitStatus().equals(VisitStatus.COOPERATIVE)) { SymptomsHelper.updateIsSymptomatic(dto.getSymptoms()); @@ -290,7 +302,7 @@ private VisitDto doSaveVisit(@Valid VisitDto dto, Visit existingVisit) { } @Override - public void validate(VisitDto visit) { + public void validate(VisitDto visit, Date allowedStartDate, Date allowedEndDate) { if (visit.getVisitStatus() == null) { throw new ValidationRuntimeException(I18nProperties.getValidationError(Validations.visitStatus)); @@ -300,6 +312,18 @@ public void validate(VisitDto visit) { } if (visit.getVisitDateTime() == null) { throw new ValidationRuntimeException(I18nProperties.getValidationError(Validations.visitDate)); + } else if (allowedStartDate != null && DateHelper.isDateBefore(visit.getVisitDateTime(), allowedStartDate)) { + throw new ValidationRuntimeException( + I18nProperties.getValidationError( + Validations.afterDate, + I18nProperties.getPrefixCaption(VisitDto.I18N_PREFIX, VisitDto.VISIT_DATE_TIME), + DateHelper.formatShortDate(allowedStartDate))); + } else if (allowedEndDate != null && DateHelper.isDateAfter(visit.getVisitDateTime(), allowedEndDate)) { + throw new ValidationRuntimeException( + I18nProperties.getValidationError( + Validations.beforeDate, + I18nProperties.getPrefixCaption(VisitDto.I18N_PREFIX, VisitDto.VISIT_DATE_TIME), + DateHelper.formatShortDate(allowedEndDate))); } if (visit.getDisease() == null) { throw new ValidationRuntimeException(I18nProperties.getValidationError(Validations.validDisease)); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/DevModeView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/DevModeView.java index 0e371b190fb..0facc595804 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/DevModeView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/DevModeView.java @@ -100,6 +100,7 @@ import de.symeda.sormas.api.utils.ValidationRuntimeException; import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; import de.symeda.sormas.api.visit.VisitDto; +import de.symeda.sormas.api.visit.VisitLogic; import de.symeda.sormas.api.visit.VisitStatus; import de.symeda.sormas.ui.UserProvider; import de.symeda.sormas.ui.configuration.generate.config.CaseGenerationConfig; @@ -948,7 +949,7 @@ private void generateCases(CaseGenerationConfig config) { // just load some health facilities. Alphabetical order is not random, but the best we can get List healthFacilities = FacadeProvider.getFacilityFacade() - .getIndexList(facilityCriteria, 0, Math.min(config.getEntityCountAsNumber() * 2, 300), Arrays.asList(new SortProperty(FacilityDto.NAME))); + .getIndexList(facilityCriteria, 0, Math.min(config.getEntityCountAsNumber() * 2, 300), Arrays.asList(new SortProperty(FacilityDto.NAME))); // Filter list, so that only health facilities meant for accomodation are selected healthFacilities.removeIf(el -> (!el.getType().isAccommodation())); @@ -1231,6 +1232,7 @@ private void generateContacts() { throw new ValidationRuntimeException(errorMessage.toString()); } } + private void generateContacts(ContactGenerationConfig contactGenerationConfig) { initializeRandomGenerator(); @@ -1270,15 +1272,15 @@ private void generateContacts(ContactGenerationConfig contactGenerationConfig) { for (int i = 0; i < contactGenerationConfig.getEntityCountAsNumber(); i++) { fieldVisibilityCheckers = - FieldVisibilityCheckers.withDisease(disease).andWithCountry(FacadeProvider.getConfigFacade().getCountryLocale()); + FieldVisibilityCheckers.withDisease(disease).andWithCountry(FacadeProvider.getConfigFacade().getCountryLocale()); LocalDateTime referenceDateTime = getReferenceDateTime( - i, - contactGenerationConfig.getEntityCountAsNumber(), - baseOffset, - disease, - contactGenerationConfig.getStartDate(), - daysBetween); + i, + contactGenerationConfig.getEntityCountAsNumber(), + baseOffset, + disease, + contactGenerationConfig.getStartDate(), + daysBetween); PersonDto person; if (contactGenerationConfig.isCreateMultipleContactsPerPerson() && !personUuids.isEmpty() && randomPercent(25)) { @@ -1346,8 +1348,8 @@ private void generateContacts(ContactGenerationConfig contactGenerationConfig) { // Create visits if (contactGenerationConfig.isCreateWithVisits() - && FacadeProvider.getDiseaseConfigurationFacade().hasFollowUp(contact.getDisease()) - && FollowUpStatus.NO_FOLLOW_UP != contact.getFollowUpStatus()) { + && FacadeProvider.getDiseaseConfigurationFacade().hasFollowUp(contact.getDisease()) + && FollowUpStatus.NO_FOLLOW_UP != contact.getFollowUpStatus()) { Date latestFollowUpDate = contact.getFollowUpUntil().before(new Date()) ? contact.getFollowUpUntil() : new Date(); Date contactStartDate = ContactLogic.getStartDate(contact); int followUpCount = random().nextInt(DateHelper.getDaysBetween(contactStartDate, latestFollowUpDate) + 1); @@ -1356,7 +1358,7 @@ private void generateContacts(ContactGenerationConfig contactGenerationConfig) { List followUpDates = new ArrayList<>(); for (int day : followUpDays) { followUpDates - .add(UtilDate.toLocalDate(contactStartDate).atStartOfDay().plusDays(day - 1).plusMinutes(random().nextInt(60 * 24 + 1))); + .add(UtilDate.toLocalDate(contactStartDate).atStartOfDay().plusDays(day - 1).plusMinutes(random().nextInt(60 * 24 + 1))); } for (LocalDateTime date : followUpDates) { @@ -1368,7 +1370,11 @@ private void generateContacts(ContactGenerationConfig contactGenerationConfig) { if (visit.getVisitStatus() == null) { visit.setVisitStatus(VisitStatus.COOPERATIVE); } - FacadeProvider.getVisitFacade().saveVisit(visit); + FacadeProvider.getVisitFacade() + .saveVisit( + visit, + VisitLogic.getAllowedStartDate(ContactLogic.getStartDate(contact)), + VisitLogic.getAllowedEndDate(ContactLogic.getEndDate(contact))); } } } @@ -1377,10 +1383,10 @@ private void generateContacts(ContactGenerationConfig contactGenerationConfig) { dt = System.nanoTime() - dt; long perContact = dt / contactGenerationConfig.getEntityCountAsNumber(); String msg = String.format( - "Generating %,d contacts took %,d ms (%,d ms per contact)", - contactGenerationConfig.getEntityCountAsNumber(), - dt / 1_000_000, - perContact / 1_000_000); + "Generating %,d contacts took %,d ms (%,d ms per contact)", + contactGenerationConfig.getEntityCountAsNumber(), + dt / 1_000_000, + perContact / 1_000_000); logger.info(msg); Notification.show("", msg, Notification.Type.TRAY_NOTIFICATION); } @@ -1415,6 +1421,7 @@ private void generateEvents() { throw new ValidationRuntimeException(errorMessage.toString()); } } + private void generateEvents(EventGenerationConfig eventGenerationConfig) { initializeRandomGenerator(); @@ -1437,8 +1444,8 @@ private void generateEvents(EventGenerationConfig eventGenerationConfig) { FacilityCriteria facilityCriteria = new FacilityCriteria(); facilityCriteria.region(eventGenerationConfig.getRegion()); facilityCriteria.district(eventGenerationConfig.getDistrict()); - List healthFacilities = FacadeProvider.getFacilityFacade() - .getIndexList(facilityCriteria, 0, (int) (maxContactsPerParticipant * percentageOfCases / 100), null); + List healthFacilities = + FacadeProvider.getFacilityFacade().getIndexList(facilityCriteria, 0, (int) (maxContactsPerParticipant * percentageOfCases / 100), null); // Filter list, so that only health facilities meant for accomodation are selected healthFacilities.removeIf(el -> (!el.getType().isAccommodation())); @@ -1456,13 +1463,25 @@ private void generateEvents(EventGenerationConfig eventGenerationConfig) { if (event.getDisease() == Disease.OTHER) { event.setDiseaseDetails("RD " + (random().nextInt(20) + 1)); } - referenceDateTime = getReferenceDateTime(i, eventGenerationConfig.getEntityCountAsNumber(), baseOffset, disease, eventGenerationConfig.getStartDate(), daysBetween); + referenceDateTime = getReferenceDateTime( + i, + eventGenerationConfig.getEntityCountAsNumber(), + baseOffset, + disease, + eventGenerationConfig.getStartDate(), + daysBetween); fieldVisibilityCheckers = - FieldVisibilityCheckers.withDisease(disease).andWithCountry(FacadeProvider.getConfigFacade().getCountryLocale()); + FieldVisibilityCheckers.withDisease(disease).andWithCountry(FacadeProvider.getConfigFacade().getCountryLocale()); } else { - referenceDateTime = getReferenceDateTime(i, eventGenerationConfig.getEntityCountAsNumber(), baseOffset, Disease.OTHER, eventGenerationConfig.getStartDate(), daysBetween); + referenceDateTime = getReferenceDateTime( + i, + eventGenerationConfig.getEntityCountAsNumber(), + baseOffset, + Disease.OTHER, + eventGenerationConfig.getStartDate(), + daysBetween); fieldVisibilityCheckers = - FieldVisibilityCheckers.withDisease(Disease.OTHER).andWithCountry(FacadeProvider.getConfigFacade().getCountryLocale()); + FieldVisibilityCheckers.withDisease(Disease.OTHER).andWithCountry(FacadeProvider.getConfigFacade().getCountryLocale()); } // title diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/visit/VisitController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/visit/VisitController.java index 6d1f2e2fef4..dac9bc9edd0 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/visit/VisitController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/visit/VisitController.java @@ -18,6 +18,7 @@ package de.symeda.sormas.ui.visit; import java.util.Collection; +import java.util.Date; import java.util.function.Consumer; import com.vaadin.server.Page; @@ -31,8 +32,10 @@ import de.symeda.sormas.api.FacadeProvider; import de.symeda.sormas.api.VisitOrigin; import de.symeda.sormas.api.caze.CaseDataDto; +import de.symeda.sormas.api.caze.CaseLogic; import de.symeda.sormas.api.caze.CaseReferenceDto; import de.symeda.sormas.api.contact.ContactDto; +import de.symeda.sormas.api.contact.ContactLogic; import de.symeda.sormas.api.contact.ContactReferenceDto; import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.i18n.Strings; @@ -42,6 +45,7 @@ import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.api.visit.VisitDto; import de.symeda.sormas.api.visit.VisitIndexDto; +import de.symeda.sormas.api.visit.VisitLogic; import de.symeda.sormas.api.visit.VisitReferenceDto; import de.symeda.sormas.ui.UserProvider; import de.symeda.sormas.ui.utils.CommitDiscardWrapperComponent; @@ -61,23 +65,41 @@ public void editVisit( boolean isEditAllowed) { VisitDto visit = FacadeProvider.getVisitFacade().getVisitByUuid(visitUuid); VisitEditForm editForm; + Date startDate = null; + Date endDate = null; if (contactRef != null) { ContactDto contact = FacadeProvider.getContactFacade().getByUuid(contactRef.getUuid()); PersonDto visitPerson = FacadeProvider.getPersonFacade().getByUuid(visit.getPerson().getUuid()); editForm = new VisitEditForm(visit.getDisease(), contact, visitPerson, false); + startDate = ContactLogic.getStartDate(contact); + endDate = ContactLogic.getEndDate(contact); } else if (caseRef != null) { CaseDataDto caze = FacadeProvider.getCaseFacade().getCaseDataByUuid(caseRef.getUuid()); PersonDto visitPerson = FacadeProvider.getPersonFacade().getByUuid(visit.getPerson().getUuid()); editForm = new VisitEditForm(visit.getDisease(), caze, visitPerson, false); + startDate = CaseLogic.getStartDate(caze); + endDate = CaseLogic.getEndDate(caze); } else { throw new IllegalArgumentException("Cannot edit a visit without contact nor case"); } editForm.setValue(visit); boolean canEdit = VisitOrigin.USER.equals(visit.getOrigin()) && isEditAllowed; - editVisit(editForm, visit.toReference(), doneConsumer, canEdit); + editVisit( + editForm, + visit.toReference(), + doneConsumer, + canEdit, + VisitLogic.getAllowedStartDate(startDate), + VisitLogic.getAllowedEndDate(endDate)); } - private void editVisit(VisitEditForm editForm, VisitReferenceDto visitRef, Consumer doneConsumer, boolean canEdit) { + private void editVisit( + VisitEditForm editForm, + VisitReferenceDto visitRef, + Consumer doneConsumer, + boolean canEdit, + Date allowedStartDate, + Date allowedEndDate) { final CommitDiscardWrapperComponent editView = new CommitDiscardWrapperComponent<>( editForm, @@ -99,7 +121,7 @@ private void editVisit(VisitEditForm editForm, VisitReferenceDto visitRef, Consu editView.addCommitListener(() -> { if (!editForm.getFieldGroup().isModified()) { - FacadeProvider.getVisitFacade().saveVisit(editForm.getValue()); + FacadeProvider.getVisitFacade().saveVisit(editForm.getValue(), allowedStartDate, allowedEndDate); if (doneConsumer != null) { doneConsumer.accept(visitRef); } @@ -117,7 +139,7 @@ private void editVisit(VisitEditForm editForm, VisitReferenceDto visitRef, Consu } } - private void createVisit(VisitEditForm createForm, Consumer doneConsumer) { + private void createVisit(VisitEditForm createForm, Consumer doneConsumer, Date allowedStartDate, Date allowedEndDate) { final CommitDiscardWrapperComponent editView = new CommitDiscardWrapperComponent( createForm, UserProvider.getCurrent().hasUserRight(UserRight.VISIT_CREATE), @@ -126,7 +148,7 @@ private void createVisit(VisitEditForm createForm, Consumer d editView.addCommitListener(() -> { if (!createForm.getFieldGroup().isModified()) { VisitDto dto = createForm.getValue(); - dto = FacadeProvider.getVisitFacade().saveVisit(dto); + dto = FacadeProvider.getVisitFacade().saveVisit(dto, allowedStartDate, allowedEndDate); if (doneConsumer != null) { doneConsumer.accept(dto.toReference()); } @@ -146,7 +168,11 @@ public void createVisit(ContactReferenceDto contactRef, Consumer doneConsumer) { @@ -156,7 +182,11 @@ public void createVisit(CaseReferenceDto caseRef, Consumer do VisitEditForm createForm = new VisitEditForm(visit.getDisease(), caze, person, true); createForm.setValue(visit); - createVisit(createForm, doneConsumer); + createVisit( + createForm, + doneConsumer, + VisitLogic.getAllowedStartDate(CaseLogic.getStartDate(caze)), + VisitLogic.getAllowedEndDate(CaseLogic.getEndDate(caze))); } private VisitDto createNewVisit(PersonReferenceDto personRef, Disease disease) { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/visit/VisitEditForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/visit/VisitEditForm.java index bdec4bf7850..cea40e0a7b7 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/visit/VisitEditForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/visit/VisitEditForm.java @@ -161,7 +161,7 @@ protected void addFields() { startDate, startDate, contact.getLastContactDate() != null ? Validations.visitBeforeLastContactDate : Validations.visitBeforeContactReport, - contact.getFollowUpUntil()); + ContactLogic.getEndDate(contact)); } if (caze != null) { From 1078ea745cae28e43157effd32c36a6f3f924394 Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Wed, 11 Jan 2023 11:53:06 +0100 Subject: [PATCH 101/166] ignore test --- .../features/sanity/web/TravelEntryFiltersUserRoles.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/TravelEntryFiltersUserRoles.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/TravelEntryFiltersUserRoles.feature index 29ec9ba22ce..15550af57c6 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/TravelEntryFiltersUserRoles.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/TravelEntryFiltersUserRoles.feature @@ -1,7 +1,7 @@ -@UI @Sanity @TravelEntries @Filters @add_userroles +@UI @Sanity @TravelEntries @Filters @add_userroles @ignore Feature: Travel entry filters for different user roles - @tmsLink=SORDEV-8267 @env_de @ignore + @tmsLink=SORDEV-8267 @env_de Scenario Outline: Check Travel Entry filters Given I log in as a And I click on the Entries button from navbar From 2acea458a16b5e5a7d266ed4afad6516d457a7ef Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Wed, 11 Jan 2023 13:02:12 +0200 Subject: [PATCH 102/166] =?UTF-8?q?#11017=20-=20Persons=20with=20incomplet?= =?UTF-8?q?e=20home=20addresses=20from=20different=20jurisd=E2=80=A6=20(#1?= =?UTF-8?q?1233)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * #11017 - Persons with incomplete home addresses from different jurisdictions can not be merged * #11017 - Persons with incomplete home addresses from different jurisdictions can not be merged * #11017 - Persons with incomplete home addresses from different jurisdictions can not be merged - changes after review * #11017 - Persons with incomplete home addresses from different jurisdictions can not be merged - changes after review * #11017 - Persons with incomplete home addresses from different jurisdictions can not be merged - changes after review * #11017 - Persons with incomplete home addresses from different jurisdictions can not be merged - changes after review * #11017 - Persons with incomplete home addresses from different jurisdictions can not be merged - changes after review * #11017 - Persons with incomplete home addresses from different jurisdictions can not be merged - changes after review --- .../de/symeda/sormas/api/i18n/Strings.java | 1 + .../src/main/resources/strings.properties | 1 + .../backend/location/LocationFacadeEjb.java | 70 ++++++ .../backend/person/PersonFacadeEjb.java | 20 +- .../symeda/sormas/backend/util/DtoHelper.java | 128 +++++----- .../backend/person/PersonFacadeEjbTest.java | 235 +++++++++++++++++- 6 files changed, 390 insertions(+), 65 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java index ed621358762..b17139b9bb2 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 @@ -1186,6 +1186,7 @@ public interface Strings { String messagePersonAlreadyEventParticipant = "messagePersonAlreadyEventParticipant"; String messagePersonContactDetailsPrimaryDuplicate = "messagePersonContactDetailsPrimaryDuplicate"; String messagePersonExternalTokenWarning = "messagePersonExternalTokenWarning"; + String messagePersonMergedAddressDescription = "messagePersonMergedAddressDescription"; String messagePersonSaved = "messagePersonSaved"; String messagePersonSavedClassificationChanged = "messagePersonSavedClassificationChanged"; String messagePlagueTypeChange = "messagePlagueTypeChange"; diff --git a/sormas-api/src/main/resources/strings.properties b/sormas-api/src/main/resources/strings.properties index 8f1eb194f5d..66739b2c9c5 100644 --- a/sormas-api/src/main/resources/strings.properties +++ b/sormas-api/src/main/resources/strings.properties @@ -1114,6 +1114,7 @@ messagePathogenTestSavedShort = Pathogen test saved messagePathogenTestsDeleted = All selected pathogen tests have been deleted messagePersonSaved = Person data saved messagePersonSavedClassificationChanged = Person data saved. The classification of at least one case associated with this person was automatically changed to %s. +messagePersonMergedAddressDescription = Adopted from discarded person during merge messagePlagueTypeChange = The symptoms selected match the clinical criteria for %s. The plague type is set to %s for this case. messagePrescriptionCreated = Prescription created messagePrescriptionSaved = Prescription saved diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/location/LocationFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/location/LocationFacadeEjb.java index dd8c44dc99e..c29f2737dd9 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/location/LocationFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/location/LocationFacadeEjb.java @@ -17,12 +17,20 @@ *******************************************************************************/ package de.symeda.sormas.backend.location; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; + import javax.ejb.EJB; import javax.ejb.LocalBean; import javax.ejb.Stateless; +import org.apache.commons.lang3.StringUtils; + import de.symeda.sormas.api.location.LocationDto; import de.symeda.sormas.api.location.LocationFacade; +import de.symeda.sormas.api.utils.DataHelper; +import de.symeda.sormas.api.uuid.HasUuid; import de.symeda.sormas.backend.infrastructure.community.CommunityFacadeEjb; import de.symeda.sormas.backend.infrastructure.community.CommunityService; import de.symeda.sormas.backend.infrastructure.continent.ContinentFacadeEjb; @@ -31,6 +39,7 @@ import de.symeda.sormas.backend.infrastructure.country.CountryService; import de.symeda.sormas.backend.infrastructure.district.DistrictFacadeEjb; import de.symeda.sormas.backend.infrastructure.district.DistrictService; +import de.symeda.sormas.backend.infrastructure.facility.Facility; import de.symeda.sormas.backend.infrastructure.facility.FacilityFacadeEjb; import de.symeda.sormas.backend.infrastructure.facility.FacilityService; import de.symeda.sormas.backend.infrastructure.region.RegionFacadeEjb; @@ -138,6 +147,67 @@ public static LocationDto toDto(Location source) { return target; } + public boolean areDifferentLocation(LocationDto firstAddress, LocationDto secondAddress) { + + java.util.function.Predicate> differentInfrastructurePredicate = (Function function) -> { + return function.apply(firstAddress) != null + && function.apply(secondAddress) != null + && !DataHelper.equal(function.apply(firstAddress).getUuid(), function.apply(secondAddress).getUuid()); + + }; + + if (Boolean.TRUE.equals(differentInfrastructurePredicate.test(LocationDto::getCountry))) { + return true; + } + + if (Boolean.TRUE.equals(differentInfrastructurePredicate.test(LocationDto::getRegion))) { + return true; + } + + if (Boolean.TRUE.equals(differentInfrastructurePredicate.test(LocationDto::getDistrict))) { + return true; + } + + if (Boolean.TRUE.equals(differentInfrastructurePredicate.test(LocationDto::getCommunity))) { + return true; + } + + if (firstAddress.getFacility() != null) { + Facility firstAddressFacilityDto = facilityService.getByUuid(firstAddress.getFacility().getUuid()); + if (secondAddress.getCommunity() != null + && firstAddressFacilityDto.getCommunity() != null + && !firstAddressFacilityDto.getCommunity().getUuid().equals(secondAddress.getCommunity().getUuid())) { + return true; + } + } + + boolean oneMatch = Boolean.FALSE; + boolean secondLocationHasAddressValues = Boolean.FALSE; + List> addressValues = new ArrayList<>(); + addressValues.add(new DataHelper.Pair<>(firstAddress.getCity(), secondAddress.getCity())); + addressValues.add(new DataHelper.Pair<>(firstAddress.getPostalCode(), secondAddress.getPostalCode())); + addressValues.add(new DataHelper.Pair<>(firstAddress.getStreet(), secondAddress.getStreet())); + addressValues.add(new DataHelper.Pair<>(firstAddress.getHouseNumber(), secondAddress.getHouseNumber())); + + for (DataHelper.Pair addressTypePair : addressValues) { + if (StringUtils.isNotBlank(addressTypePair.getElement0()) && StringUtils.isNotBlank(addressTypePair.getElement1())) { + if (!DataHelper.equal(addressTypePair.getElement0(), addressTypePair.getElement1())) { + return true; + } else { + oneMatch = Boolean.TRUE; + } + } else if (addressTypePair.getElement1() != null) { + secondLocationHasAddressValues = Boolean.TRUE; + } + } + + if (secondLocationHasAddressValues) { + return !oneMatch; + } + + return false; + } + @LocalBean @Stateless public static class LocationFacadeEjbLocal extends LocationFacadeEjb { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java index c31c36c0fa3..6eb761ecfee 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java @@ -95,6 +95,7 @@ import de.symeda.sormas.api.person.ApproximateAgeType.ApproximateAgeHelper; import de.symeda.sormas.api.person.CauseOfDeath; import de.symeda.sormas.api.person.JournalPersonDto; +import de.symeda.sormas.api.person.PersonAddressType; import de.symeda.sormas.api.person.PersonAssociation; import de.symeda.sormas.api.person.PersonContactDetailDto; import de.symeda.sormas.api.person.PersonContactDetailType; @@ -1787,7 +1788,9 @@ public void mergePerson(PersonDto leadPerson, PersonDto otherPerson) { } } - DtoHelper.copyDtoValues(leadPerson, otherPerson, false); + DtoHelper.copyDtoValues(leadPerson, otherPerson, false, PersonDto.ADDRESS); + processPersonAddressMerge(leadPerson, otherPerson); + save(leadPerson); } @@ -1815,7 +1818,9 @@ public void mergePerson(String leadPersonUuid, String otherPersonUuid, boolean m contactDetailDto.setPrimaryContact(false); } } - DtoHelper.copyDtoValues(leadPersonDto, otherPersonDto, false); + + DtoHelper.copyDtoValues(leadPersonDto, otherPersonDto, false, PersonDto.ADDRESS); + processPersonAddressMerge(leadPersonDto, otherPersonDto); save(leadPersonDto); } @@ -1859,6 +1864,17 @@ public void mergePerson(String leadPersonUuid, String otherPersonUuid, boolean m service.ensurePersisted(leadPerson); } + private void processPersonAddressMerge(PersonDto leadPersonDto, PersonDto otherPersonDto) { + if (locationFacade.areDifferentLocation(leadPersonDto.getAddress(), otherPersonDto.getAddress())) { + LocationDto otherAddress = otherPersonDto.getAddress(); + otherAddress.setAddressType(PersonAddressType.OTHER_ADDRESS); + otherAddress.setAddressTypeDetails(I18nProperties.getString(Strings.messagePersonMergedAddressDescription)); + leadPersonDto.addAddress(otherAddress); + } else { + DtoHelper.copyDtoValues(leadPersonDto.getAddress(), otherPersonDto.getAddress(), false); + } + } + @Override public boolean isPersonSimilar(PersonSimilarityCriteria criteria, String personUuid) { return service.isPersonSimilar(criteria, personUuid); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/util/DtoHelper.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/util/DtoHelper.java index d61e8c3571f..e2919607c7e 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/util/DtoHelper.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/util/DtoHelper.java @@ -22,6 +22,7 @@ import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.sql.Timestamp; +import java.util.Arrays; import java.util.Collection; import java.util.EnumMap; import java.util.Map; @@ -66,6 +67,10 @@ public static void fillDto(EntityDto dto, AbstractDomainObject entity) { dto.setUuid(entity.getUuid()); } + public static T copyDtoValues(T target, T source, boolean overrideValues) { + return copyDtoValues(target, source, overrideValues, null); + } + /** * @param overrideValues * Note: Existing references are NOT overridden @@ -73,7 +78,7 @@ public static void fillDto(EntityDto dto, AbstractDomainObject entity) { @SuppressWarnings({ "unchecked", "rawtypes" }) - public static T copyDtoValues(T target, T source, boolean overrideValues) { + public static T copyDtoValues(T target, T source, boolean overrideValues, String... skippedFields) { try { PropertyDescriptor[] pds = Introspector.getBeanInfo(target.getClass(), EntityDto.class).getPropertyDescriptors(); @@ -91,78 +96,81 @@ public static T copyDtoValues(T target, T source, boolean continue; } - if (EntityDto.class.isAssignableFrom(pd.getPropertyType())) { - - if (targetValue == null) { - targetValue = sourceValue.getClass().newInstance(); - pd.getWriteMethod().invoke(target, targetValue); - } - - // If both entities have the same UUID, assign a new one to targetValue to create a new entity - if (((EntityDto) targetValue).getUuid().equals(((EntityDto) sourceValue).getUuid())) { - ((EntityDto) targetValue).setUuid(DataHelper.createUuid()); - } - - // entity: just fill the existing one with the source - copyDtoValues((EntityDto) targetValue, (EntityDto) sourceValue, overrideValues); - } else { - boolean override = overrideValues && !ReferenceDto.class.isAssignableFrom(pd.getPropertyType()); - // should we write into the target property? - if (Collection.class.isAssignableFrom(pd.getPropertyType())) { + if (skippedFields == null || Arrays.stream(skippedFields).noneMatch(field -> field.equals(pd.getName()))) { + if (EntityDto.class.isAssignableFrom(pd.getPropertyType())) { if (targetValue == null) { targetValue = sourceValue.getClass().newInstance(); pd.getWriteMethod().invoke(target, targetValue); } - Collection targetCollection = (Collection) targetValue; - - for (Object sourceEntry : (Collection) sourceValue) { - if (sourceEntry instanceof EntityDto) { - EntityDto newEntry = ((EntityDto) sourceEntry).clone(); - newEntry.setUuid(DataHelper.createUuid()); - newEntry.setCreationDate(null); - copyDtoValues(newEntry, (EntityDto) sourceEntry, true); - targetCollection.add(newEntry); - } else if (DataHelper.isValueType(sourceEntry.getClass()) - || sourceEntry instanceof ReferenceDto - || sourceEntry instanceof JsonDataEntry) { - targetCollection.add(sourceEntry); - } else { - throw new UnsupportedOperationException(pd.getPropertyType().getName() + " is not supported as a list entry type."); - } + // If both entities have the same UUID, assign a new one to targetValue to create a new entity + if (((EntityDto) targetValue).getUuid().equals(((EntityDto) sourceValue).getUuid())) { + ((EntityDto) targetValue).setUuid(DataHelper.createUuid()); } - } else if (Map.class.isAssignableFrom(pd.getPropertyType())) { - if (targetValue == null) { - if (sourceValue.getClass() == EnumMap.class) { - // Enum map needs to be initialized with the content of the source map because it does not have an init method - targetValue = Maps.newEnumMap((EnumMap) sourceValue); - ((EnumMap) targetValue).clear(); - } else { + // entity: just fill the existing one with the source + copyDtoValues((EntityDto) targetValue, (EntityDto) sourceValue, overrideValues); + } else { + boolean override = overrideValues && !ReferenceDto.class.isAssignableFrom(pd.getPropertyType()); + // should we write into the target property? + if (Collection.class.isAssignableFrom(pd.getPropertyType())) { + + if (targetValue == null) { targetValue = sourceValue.getClass().newInstance(); + pd.getWriteMethod().invoke(target, targetValue); } - pd.getWriteMethod().invoke(target, targetValue); - } - Map targetMap = (Map) targetValue; + Collection targetCollection = (Collection) targetValue; + + for (Object sourceEntry : (Collection) sourceValue) { + if (sourceEntry instanceof EntityDto) { + EntityDto newEntry = ((EntityDto) sourceEntry).clone(); + newEntry.setUuid(DataHelper.createUuid()); + newEntry.setCreationDate(null); + copyDtoValues(newEntry, (EntityDto) sourceEntry, true); + targetCollection.add(newEntry); + } else if (DataHelper.isValueType(sourceEntry.getClass()) + || sourceEntry instanceof ReferenceDto + || sourceEntry instanceof JsonDataEntry) { + targetCollection.add(sourceEntry); + } else { + throw new UnsupportedOperationException( + pd.getPropertyType().getName() + " is not supported as a list entry type."); + } + } + } else if (Map.class.isAssignableFrom(pd.getPropertyType())) { + + if (targetValue == null) { + if (sourceValue.getClass() == EnumMap.class) { + // Enum map needs to be initialized with the content of the source map because it does not have an init method + targetValue = Maps.newEnumMap((EnumMap) sourceValue); + ((EnumMap) targetValue).clear(); + } else { + targetValue = sourceValue.getClass().newInstance(); + } + pd.getWriteMethod().invoke(target, targetValue); + } + + Map targetMap = (Map) targetValue; - for (Object sourceKey : ((Map) sourceValue).keySet()) { - if (override || !targetMap.containsKey(sourceKey)) { - targetMap.put(sourceKey, ((Map) sourceValue).get(sourceKey)); + for (Object sourceKey : ((Map) sourceValue).keySet()) { + if (override || !targetMap.containsKey(sourceKey)) { + targetMap.put(sourceKey, ((Map) sourceValue).get(sourceKey)); + } + } + } else if (targetValue == null + || override + || (pd.getPropertyType().equals(String.class) + && StringUtils.isBlank((String) targetValue) + && StringUtils.isNotBlank((String) sourceValue)) + || (pd.getPropertyType().equals(boolean.class) && ((boolean) sourceValue) && !((boolean) targetValue))) { + if (DataHelper.isValueType(pd.getPropertyType()) || ReferenceDto.class.isAssignableFrom(pd.getPropertyType())) { + pd.getWriteMethod().invoke(target, sourceValue); + } else { + // Other objects are not supported + throw new UnsupportedOperationException(pd.getPropertyType().getName() + " is not supported as a property type."); } - } - } else if (targetValue == null - || override - || (pd.getPropertyType().equals(String.class) - && StringUtils.isBlank((String) targetValue) - && StringUtils.isNotBlank((String) sourceValue)) - || (pd.getPropertyType().equals(boolean.class) && ((boolean) sourceValue) && !((boolean) targetValue))) { - if (DataHelper.isValueType(pd.getPropertyType()) || ReferenceDto.class.isAssignableFrom(pd.getPropertyType())) { - pd.getWriteMethod().invoke(target, sourceValue); - } else { - // Other objects are not supported - throw new UnsupportedOperationException(pd.getPropertyType().getName() + " is not supported as a property type."); } } } diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/person/PersonFacadeEjbTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/person/PersonFacadeEjbTest.java index 8ffb447d945..d9ebf8db71b 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/person/PersonFacadeEjbTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/person/PersonFacadeEjbTest.java @@ -15,6 +15,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; @@ -22,6 +23,9 @@ import java.util.Optional; import java.util.stream.Collectors; +import de.symeda.sormas.api.infrastructure.country.CountryDto; +import de.symeda.sormas.api.infrastructure.country.CountryReferenceDto; +import de.symeda.sormas.backend.infrastructure.country.Country; import org.junit.jupiter.api.Test; import de.symeda.sormas.api.CountryHelper; @@ -38,13 +42,19 @@ import de.symeda.sormas.api.event.EventDto; import de.symeda.sormas.api.event.EventParticipantDto; import de.symeda.sormas.api.externalsurveillancetool.ExternalSurveillanceToolRuntimeException; +import de.symeda.sormas.api.i18n.I18nProperties; +import de.symeda.sormas.api.i18n.Strings; import de.symeda.sormas.api.immunization.ImmunizationDto; import de.symeda.sormas.api.immunization.ImmunizationManagementStatus; import de.symeda.sormas.api.immunization.ImmunizationStatus; import de.symeda.sormas.api.immunization.MeansOfImmunization; +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.infrastructure.region.RegionReferenceDto; import de.symeda.sormas.api.location.LocationDto; import de.symeda.sormas.api.person.JournalPersonDto; +import de.symeda.sormas.api.person.PersonAddressType; import de.symeda.sormas.api.person.PersonAssociation; import de.symeda.sormas.api.person.PersonContactDetailDto; import de.symeda.sormas.api.person.PersonContactDetailType; @@ -76,6 +86,10 @@ import de.symeda.sormas.backend.TestDataCreator; import de.symeda.sormas.backend.TestDataCreator.RDCF; import de.symeda.sormas.backend.common.ConfigFacadeEjb; +import de.symeda.sormas.backend.infrastructure.community.Community; +import de.symeda.sormas.backend.infrastructure.district.District; +import de.symeda.sormas.backend.infrastructure.facility.Facility; +import de.symeda.sormas.backend.infrastructure.region.Region; import de.symeda.sormas.backend.user.User; public class PersonFacadeEjbTest extends AbstractBeanTest { @@ -926,8 +940,36 @@ public void testMergePersonsAndRemoveDuplication() { otherPerson.setPhone("+496211218491"); leadPerson.setEmailAddress("lead@hotmail.com"); otherPerson.setEmailAddress("other@yahoo.com"); - leadPerson.setAddresses(Collections.singletonList(LocationDto.build())); - otherPerson.setAddresses(Collections.singletonList(LocationDto.build())); + + TestDataCreator.RDCFEntities rdcf1 = creator.createRDCFEntities("Region", "District", "Community", "Facility"); + TestDataCreator.RDCFEntities rdcf2 = creator.createRDCFEntities("Region2", "District2", "Community2", "Facility2"); + TestDataCreator.RDCFEntities rdcf3 = creator.createRDCFEntities("Region3", "District3", "Community3", "Facility3"); + TestDataCreator.RDCFEntities rdcf4 = creator.createRDCFEntities("Region4", "District4", "Community4", "Facility4"); + + LocationDto leadPersonAddress = leadPerson.getAddress(); + leadPersonAddress.setRegion(new RegionReferenceDto(rdcf1.region.getUuid())); + leadPersonAddress.setDistrict(new DistrictReferenceDto(rdcf1.district.getUuid())); + + LocationDto otherPersonAddress = otherPerson.getAddress(); + otherPersonAddress.setRegion(new RegionReferenceDto(rdcf2.region.getUuid())); + otherPersonAddress.setDistrict(new DistrictReferenceDto(rdcf2.district.getUuid())); + otherPersonAddress.setCommunity(new CommunityReferenceDto(rdcf2.community.getUuid())); + + List leadAddresses = new ArrayList<>(); + LocationDto leadAddresses1 = LocationDto.build(); + leadAddresses1.setRegion(new RegionReferenceDto(rdcf3.region.getUuid())); + leadAddresses1.setDistrict(new DistrictReferenceDto(rdcf3.district.getUuid())); + leadAddresses1.setCommunity(new CommunityReferenceDto(rdcf3.community.getUuid())); + leadAddresses.add(leadAddresses1); + + LocationDto leadAddresses2 = LocationDto.build(); + leadAddresses2.setRegion(new RegionReferenceDto(rdcf4.region.getUuid())); + leadAddresses2.setDistrict(new DistrictReferenceDto(rdcf4.district.getUuid())); + leadAddresses.add(leadAddresses2); + + leadPerson.setAddresses(leadAddresses); + leadPerson.setAddress(leadPersonAddress); + otherPerson.setAddress(otherPersonAddress); leadPerson = getPersonFacade().save(leadPerson); otherPerson = getPersonFacade().save(otherPerson); @@ -960,7 +1002,7 @@ public void testMergePersonsAndRemoveDuplication() { assertEquals(1, getVisitService().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); assertEquals(1, leadPerson.getAllEmailAddresses().size()); assertEquals(1, leadPerson.getAllPhoneNumbers().size()); - assertEquals(1, leadPerson.getAddresses().size()); + assertEquals(2, leadPerson.getAddresses().size()); assertTrue(getPersonFacade().exists(otherPerson.getUuid())); getPersonFacade().mergePerson(leadPerson.getUuid(), otherPerson.getUuid(), true); @@ -979,10 +1021,197 @@ public void testMergePersonsAndRemoveDuplication() { List leadPersonAllPhoneNumbers = leadPerson.getAllPhoneNumbers(); assertEquals(2, leadPersonAllPhoneNumbers.size()); assertEquals(1, leadPersonAllPhoneNumbers.stream().filter(s -> s.equals("+496211218490")).count()); + assertEquals(rdcf1.region.getUuid(), leadPerson.getAddress().getRegion().getUuid()); + assertNull(leadPerson.getAddress().getCommunity()); + assertEquals(3, leadPerson.getAddresses().size()); + assertEquals(1, leadPerson.getAddresses().stream().filter(field -> field.getUuid().equals(leadAddresses1.getUuid())).count()); + assertEquals(1, leadPerson.getAddresses().stream().filter(field -> field.getUuid().equals(leadAddresses2.getUuid())).count()); + assertEquals(1, leadPerson.getAddresses().stream().filter(field -> otherPersonAddress.getDistrict().equals(field.getDistrict())).count()); + assertFalse(getPersonFacade().exists(otherPerson.getUuid())); + } + + @Test + public void testMergePersonsSameMainAddress() { + + PersonDto leadPerson = creator.createPerson("John", "Doe", Sex.MALE, 1980, 1, 1, "000111222", null); + PersonDto otherPerson = creator.createPerson("James", "Smith", Sex.MALE, 1990, 1, 1, "444555666", "123456789"); + + leadPerson.setPhone("+496211218490"); + otherPerson.setPhone("+496211218491"); + leadPerson.setEmailAddress("lead@hotmail.com"); + otherPerson.setEmailAddress("other@yahoo.com"); + + TestDataCreator.RDCFEntities rdcf1 = creator.createRDCFEntities("Region", "District", "Community", "Facility"); + TestDataCreator.RDCFEntities rdcf3 = creator.createRDCFEntities("Region3", "District3", "Community3", "Facility3"); + TestDataCreator.RDCFEntities rdcf4 = creator.createRDCFEntities("Region4", "District4", "Community4", "Facility4"); + + LocationDto leadPersonAddress = leadPerson.getAddress(); + leadPersonAddress.setRegion(new RegionReferenceDto(rdcf1.region.getUuid())); + leadPersonAddress.setDistrict(new DistrictReferenceDto(rdcf1.district.getUuid())); + + Country country = creator.createCountry("Romania", "ROU", "642"); + getCountryService().doFlush(); + CountryReferenceDto countryReferenceDto = getCountryFacade().getReferenceByUuid(country.getUuid()); + leadPersonAddress.setCountry(countryReferenceDto); + + LocationDto otherPersonAddress = otherPerson.getAddress(); + otherPersonAddress.setRegion(new RegionReferenceDto(rdcf1.region.getUuid())); + otherPersonAddress.setDistrict(new DistrictReferenceDto(rdcf1.district.getUuid())); + otherPersonAddress.setCommunity(new CommunityReferenceDto(rdcf1.community.getUuid())); + + List leadAddresses = new ArrayList<>(); + LocationDto leadAddresses1 = LocationDto.build(); + leadAddresses1.setRegion(new RegionReferenceDto(rdcf3.region.getUuid())); + leadAddresses1.setDistrict(new DistrictReferenceDto(rdcf3.district.getUuid())); + leadAddresses1.setCommunity(new CommunityReferenceDto(rdcf3.community.getUuid())); + leadAddresses.add(leadAddresses1); + + LocationDto leadAddresses2 = LocationDto.build(); + leadAddresses2.setRegion(new RegionReferenceDto(rdcf4.region.getUuid())); + leadAddresses2.setDistrict(new DistrictReferenceDto(rdcf4.district.getUuid())); + leadAddresses.add(leadAddresses2); + + leadPerson.setAddresses(leadAddresses); + leadPerson.setAddress(leadPersonAddress); + otherPerson.setAddress(otherPersonAddress); + + leadPerson = getPersonFacade().save(leadPerson); + otherPerson = getPersonFacade().save(otherPerson); + + final PersonReferenceDto leadPersonRef = leadPerson.toReference(); + final PersonReferenceDto otherPersonRef = otherPerson.toReference(); + final UserReferenceDto natUserRef = nationalUser.toReference(); + + final CaseDataDto leadCase = creator.createCase(natUserRef, leadPersonRef, rdcfEntities); + creator.createContact(natUserRef, leadPersonRef); + final EventDto leadEvent = creator.createEvent(natUserRef); + creator.createEventParticipant(leadEvent.toReference(), leadPerson, natUserRef); + creator.createVisit(leadPersonRef); + creator.createImmunization(Disease.CORONAVIRUS, leadPersonRef, natUserRef, rdcf); + creator.createTravelEntry(leadPersonRef, natUserRef, rdcf, te -> te.setResultingCase(leadCase.toReference())); + + final CaseDataDto otherCase = creator.createCase(natUserRef, otherPersonRef, rdcfEntities); + creator.createContact(natUserRef, otherPersonRef); + final EventDto otherEvent = creator.createEvent(natUserRef); + creator.createEventParticipant(otherEvent.toReference(), otherPerson, natUserRef); + creator.createVisit(otherPersonRef); + creator.createImmunization(Disease.CORONAVIRUS, otherPersonRef, natUserRef, rdcf); + creator.createTravelEntry(otherPersonRef, natUserRef, rdcf, te -> te.setResultingCase(otherCase.toReference())); + + assertEquals(1, getCaseFacade().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(1, getContactFacade().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(1, getEventParticipantFacade().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(1, getImmunizationFacade().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(1, getTravelEntryFacade().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(1, getVisitService().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(1, leadPerson.getAllEmailAddresses().size()); + assertEquals(1, leadPerson.getAllPhoneNumbers().size()); + assertEquals(2, leadPerson.getAddresses().size()); + assertTrue(getPersonFacade().exists(otherPerson.getUuid())); + assertNull(leadPerson.getAddress().getCommunity()); + + getPersonFacade().mergePerson(leadPerson.getUuid(), otherPerson.getUuid(), true); + + leadPerson = getPersonFacade().getByUuid(leadPerson.getUuid()); + + assertEquals(2, getCaseFacade().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(2, getContactFacade().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(2, getEventParticipantFacade().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(2, getImmunizationFacade().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(2, getTravelEntryFacade().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + assertEquals(2, getVisitService().getByPersonUuids(Collections.singletonList(leadPerson.getUuid())).size()); + + assertNotNull(leadPerson.getAddress().getCommunity()); assertEquals(2, leadPerson.getAddresses().size()); assertFalse(getPersonFacade().exists(otherPerson.getUuid())); } + @Test + public void testMergePersonsLeadPersonFacilityNotMatchInfrastructureDataFromOtherPerson() { + PersonDto leadPerson = creator.createPerson("John", "Doe", Sex.MALE, 1980, 1, 1, "000111222", null); + PersonDto otherPerson = creator.createPerson("James", "Smith", Sex.MALE, 1990, 1, 1, "444555666", "123456789"); + + leadPerson.setPhone("+496211218490"); + otherPerson.setPhone("+496211218491"); + leadPerson.setEmailAddress("lead@hotmail.com"); + otherPerson.setEmailAddress("other@yahoo.com"); + + Region region = creator.createRegion("Region"); + District district = creator.createDistrict("District", region); + Community community1 = creator.createCommunity("Community1", district); + Facility facility1 = creator.createFacility("Facility1", region, district, community1); + Community community2 = creator.createCommunity("Community2", district); + Facility facility2 = creator.createFacility("Facility2", region, district, community2); + + TestDataCreator.RDCFEntities rdcf1 = new TestDataCreator.RDCFEntities(region, district, community1, facility1); + TestDataCreator.RDCFEntities rdcf2 = new TestDataCreator.RDCFEntities(region, district, community2, facility2); + TestDataCreator.RDCFEntities rdcf3 = creator.createRDCFEntities("Region3", "District3", "Community3", "Facility3"); + TestDataCreator.RDCFEntities rdcf4 = creator.createRDCFEntities("Region4", "District4", "Community4", "Facility4"); + + LocationDto leadPersonAddress = leadPerson.getAddress(); + leadPersonAddress.setRegion(new RegionReferenceDto(rdcf1.region.getUuid())); + leadPersonAddress.setDistrict(new DistrictReferenceDto(rdcf1.district.getUuid())); + leadPersonAddress.setFacility(new FacilityReferenceDto(rdcf1.facility.getUuid())); + + LocationDto otherPersonAddress = otherPerson.getAddress(); + otherPersonAddress.setRegion(new RegionReferenceDto(rdcf2.region.getUuid())); + otherPersonAddress.setDistrict(new DistrictReferenceDto(rdcf2.district.getUuid())); + otherPersonAddress.setCommunity(new CommunityReferenceDto(rdcf2.community.getUuid())); + + List leadAddresses = new ArrayList<>(); + LocationDto leadAddresses1 = LocationDto.build(); + leadAddresses1.setRegion(new RegionReferenceDto(rdcf3.region.getUuid())); + leadAddresses1.setDistrict(new DistrictReferenceDto(rdcf3.district.getUuid())); + leadAddresses1.setCommunity(new CommunityReferenceDto(rdcf3.community.getUuid())); + leadAddresses.add(leadAddresses1); + + LocationDto leadAddresses2 = LocationDto.build(); + leadAddresses2.setRegion(new RegionReferenceDto(rdcf4.region.getUuid())); + leadAddresses2.setDistrict(new DistrictReferenceDto(rdcf4.district.getUuid())); + leadAddresses.add(leadAddresses2); + + leadPerson.setAddresses(leadAddresses); + leadPerson.setAddress(leadPersonAddress); + otherPerson.setAddress(otherPersonAddress); + + leadPerson = getPersonFacade().save(leadPerson); + otherPerson = getPersonFacade().save(otherPerson); + + assertEquals(1, leadPerson.getAllEmailAddresses().size()); + assertEquals(1, leadPerson.getAllPhoneNumbers().size()); + assertEquals(2, leadPerson.getAddresses().size()); + assertTrue(getPersonFacade().exists(otherPerson.getUuid())); + assertNull(leadPerson.getAddress().getCommunity()); + + getPersonFacade().mergePerson(leadPerson.getUuid(), otherPerson.getUuid(), true); + + leadPerson = getPersonFacade().getByUuid(leadPerson.getUuid()); + + assertEquals(3, leadPerson.getAddresses().size()); + assertEquals(rdcf1.region.getUuid(), leadPerson.getAddress().getRegion().getUuid()); + assertEquals(rdcf1.district.getUuid(), leadPerson.getAddress().getDistrict().getUuid()); + assertNull(leadPerson.getAddress().getCommunity()); + assertEquals(1, leadPerson.getAddresses().stream().filter(field -> field.getUuid().equals(leadAddresses1.getUuid())).count()); + assertEquals(1, leadPerson.getAddresses().stream().filter(field -> field.getUuid().equals(leadAddresses2.getUuid())).count()); + assertEquals(1, leadPerson.getAddresses().stream().filter(field -> otherPersonAddress.getCommunity().equals(field.getCommunity())).count()); + assertEquals( + PersonAddressType.OTHER_ADDRESS, + leadPerson.getAddresses() + .stream() + .filter(field -> field.getUuid().equals(otherPersonAddress.getUuid())) + .findFirst() + .get() + .getAddressType()); + assertEquals( + I18nProperties.getString(Strings.messagePersonMergedAddressDescription), + leadPerson.getAddresses() + .stream() + .filter(field -> field.getUuid().equals(otherPersonAddress.getUuid())) + .findFirst() + .get() + .getAddressTypeDetails()); + } + private void updateFollowUpStatus(ContactDto contact, FollowUpStatus status) { contact = getContactFacade().getByUuid(contact.getUuid()); contact.setFollowUpStatus(status); From d9035818e17df376d5aebb7775781b4cd44fab70 Mon Sep 17 00:00:00 2001 From: Bartha Barna Date: Wed, 11 Jan 2023 13:27:51 +0200 Subject: [PATCH 103/166] Change 9759 to string to build caption (#11163) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * #9759 - adjust toString of dto-s - introduce HasCaption interface * #9759 - adjust toString methods in android + replace where needed with buildCaption * #9759 - adjust usages of ReferenceDto for vaadin 7 fields * #9759 - fix vaadin 8 combobox captions - fix captions of grids using vaadin 7 * #9759 - fix captions of country combos * #9759 - fix captions of standalone combos and conbos that are disabled and are filled only with one value from the dto * #9759 - cleanup * #9759 - use correct captions in various grids and fields * #9759 - replace toString with caption on doc generation * #9759 - remove commented code - revert caption related changes to case filter form as they are fixed now in a generic way * #9759 - use captions in campaign related forms * #9759 - use captions in specific grids and fields * #9759 - replace all remaining implicit toString calls of ReferenceDto with buildCaption * #9759 - replace all remaining implicit toString calls of AbstractDomainObject with buildCaption on android Co-authored-by: Maté Strysewske --- .../java/de/symeda/sormas/api/EntityDto.java | 3 +- .../sormas/api/EntityDtoAccessHelper.java | 4 +- .../de/symeda/sormas/api/ReferenceDto.java | 11 ++++- .../de/symeda/sormas/api/caze/MapCaseDto.java | 4 +- .../api/contact/ContactReferenceDto.java | 9 ++-- .../sormas/api/contact/MapContactDto.java | 3 +- .../api/dashboard/DashboardEventDto.java | 2 +- .../sormas/api/event/EventIndexDto.java | 6 +-- .../sormas/api/person/JournalPersonDto.java | 2 +- .../sormas/api/person/SimilarPersonDto.java | 6 ++- .../symeda/sormas/api/utils/DataHelper.java | 7 +++ .../symeda/sormas/api/utils/HasCaption.java | 22 +++++++++ .../sormas/api/uuid/AbstractUuidDto.java | 17 ++++++- .../sormas/app/backend/campaign/Campaign.java | 14 +++--- .../campaign/data/CampaignFormData.java | 2 +- .../campaign/form/CampaignFormMeta.java | 10 ++--- .../symeda/sormas/app/backend/caze/Case.java | 4 +- .../sormas/app/backend/caze/CaseDao.java | 2 +- .../DiseaseClassificationCriteria.java | 8 ++-- .../app/backend/common/AbstractAdoDao.java | 28 ++++++------ .../backend/common/AbstractDomainObject.java | 33 ++++++++------ .../app/backend/common/AdoDtoHelper.java | 16 +++---- .../sormas/app/backend/contact/Contact.java | 12 ++--- .../sormas/app/backend/event/Event.java | 2 +- .../app/backend/event/EventParticipant.java | 10 ++--- .../sormas/app/backend/facility/Facility.java | 12 ++--- .../PreviousHospitalization.java | 12 ++--- .../immunization/ImmunizationDtoHelper.java | 2 +- .../backend/infrastructure/PointOfEntry.java | 8 ++-- .../sormas/app/backend/location/Location.java | 18 ++++---- .../sormas/app/backend/person/Person.java | 18 ++++---- .../backend/person/PersonContactDetail.java | 2 +- .../sormas/app/backend/region/Area.java | 2 +- .../sormas/app/backend/region/Community.java | 8 ++-- .../sormas/app/backend/region/Continent.java | 2 +- .../sormas/app/backend/region/Country.java | 2 +- .../sormas/app/backend/region/District.java | 2 +- .../sormas/app/backend/region/Region.java | 2 +- .../app/backend/region/Subcontinent.java | 8 ++-- .../app/backend/sample/PathogenTest.java | 16 +++---- .../sormas/app/backend/sample/Sample.java | 16 +++---- .../symeda/sormas/app/backend/user/User.java | 8 ++-- .../sormas/app/backend/visit/Visit.java | 12 ++--- .../controls/ControlTextReadField.java | 14 +++--- .../app/core/TaskNotificationService.java | 12 ++--- .../aggregate/AggregateReportsFragment.java | 2 +- .../sormas/app/settings/SettingsFragment.java | 14 +++--- .../de/symeda/sormas/app/util/DataUtils.java | 9 +++- .../sormas/app/util/FormBindingAdapters.java | 18 ++++---- .../app/util/TextViewBindingAdapters.java | 42 ++++++++--------- .../res/layout/fragment_task_edit_layout.xml | 6 +-- .../layout/fragment_task_execution_layout.xml | 6 +-- .../form/CampaignFormMetaFacadeEjb.java | 2 +- .../sormas/backend/TestDataCreator.java | 2 +- .../ui/campaign/CampaignController.java | 4 +- .../campaigndata/CampaignDataView.java | 4 +- .../CampaignFormDataSelectionField.java | 8 ++-- .../campaigndata/CampaignFormDataView.java | 4 +- .../campaigns/CampaignFormsGridComponent.java | 1 - .../campaign/components/CampaignSelector.java | 1 + .../importer/CampaignFormDataImporter.java | 4 +- .../symeda/sormas/ui/caze/CaseInfoLayout.java | 2 +- .../sormas/ui/caze/CasePickOrCreateField.java | 6 +-- .../ui/caze/ConvertToCaseSelectionField.java | 4 +- .../ui/caze/MergeCasesFilterComponent.java | 2 + .../linelisting/LineListingLayout.java | 4 ++ .../caze/importer/CasePickOrImportField.java | 10 ++--- .../sormas/ui/configuration/DevModeView.java | 9 ++++ .../components/CountryCombo.java | 4 +- .../LineListingConfigurationView.java | 4 +- .../linelisting/LineListingRegionsLayout.java | 2 +- .../outbreak/OutbreakController.java | 2 +- .../outbreak/OutbreakOverviewGrid.java | 6 ++- .../OutbreakRegionConfigurationForm.java | 2 +- .../contact/MergeContactsFilterComponent.java | 2 + .../sharedinfo/SharedInfoField.java | 3 ++ .../docgeneration/QuarantineOrderLayout.java | 2 + .../sormas/ui/exposure/ExposuresField.java | 4 +- .../hospitalization/HospitalizationForm.java | 2 +- .../ui/person/PersonSelectionField.java | 4 +- .../ui/reports/WeeklyReportOfficersGrid.java | 2 +- .../ui/reports/WeeklyReportRegionsGrid.java | 6 ++- .../aggregate/AggregateReportsEditLayout.java | 4 ++ .../sormas/ui/samples/AbstractSampleForm.java | 2 +- .../sormas/ui/samples/SampleController.java | 4 +- .../ui/sormastosormas/CasePreviewGrid.java | 7 +++ .../sormastosormas/ContactsPreviewGrid.java | 6 +++ .../de/symeda/sormas/ui/user/UserGrid.java | 3 -- .../sormas/ui/utils/CaptionRenderer.java | 8 ++-- .../sormas/ui/utils/ComboBoxHelper.java | 5 +-- .../ui/utils/ComboBoxWithPlaceholder.java | 27 +++++++++++ .../symeda/sormas/ui/utils/FilteredGrid.java | 9 ++++ .../ui/utils/OptionGroupWithCaption.java | 34 ++++++++++++++ .../utils/SormasFieldGroupFieldFactory.java | 5 +++ .../sormas/ui/utils/V7CaptionConverter.java | 45 +++++++++++++++++++ 95 files changed, 505 insertions(+), 276 deletions(-) create mode 100644 sormas-api/src/main/java/de/symeda/sormas/api/utils/HasCaption.java create mode 100644 sormas-ui/src/main/java/de/symeda/sormas/ui/utils/OptionGroupWithCaption.java create mode 100644 sormas-ui/src/main/java/de/symeda/sormas/ui/utils/V7CaptionConverter.java diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/EntityDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/EntityDto.java index 0c90b823ff2..f0421e278c8 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/EntityDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/EntityDto.java @@ -29,6 +29,7 @@ import de.symeda.sormas.api.audit.AuditedClass; import de.symeda.sormas.api.i18n.Validations; import de.symeda.sormas.api.utils.FieldConstraints; +import de.symeda.sormas.api.utils.HasCaption; import de.symeda.sormas.api.utils.Outbreaks; import de.symeda.sormas.api.uuid.HasUuid; @@ -43,7 +44,7 @@ */ @AuditedClass @JsonInclude(JsonInclude.Include.NON_NULL) -public abstract class EntityDto implements Serializable, Cloneable, HasUuid { +public abstract class EntityDto implements Serializable, Cloneable, HasUuid, HasCaption { private static final long serialVersionUID = -1L; diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/EntityDtoAccessHelper.java b/sormas-api/src/main/java/de/symeda/sormas/api/EntityDtoAccessHelper.java index 6cb86012e1b..c8c993eabd8 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/EntityDtoAccessHelper.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/EntityDtoAccessHelper.java @@ -22,12 +22,13 @@ import java.util.HashMap; import java.util.Map; -import de.symeda.sormas.api.uuid.HasUuid; import org.apache.commons.lang3.StringUtils; import de.symeda.sormas.api.caze.BirthDateDto; import de.symeda.sormas.api.caze.BurialInfoDto; import de.symeda.sormas.api.utils.DataHelper; +import de.symeda.sormas.api.utils.HasCaption; +import de.symeda.sormas.api.uuid.HasUuid; public class EntityDtoAccessHelper { @@ -114,6 +115,7 @@ public static Object formatObject(Object value) { } else if (value instanceof Date || value instanceof BurialInfoDto || value instanceof BirthDateDto + || value instanceof HasCaption || value.getClass().equals(Boolean.class)) { return DataHelper.valueToString(value); } else { diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/ReferenceDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/ReferenceDto.java index 7c3132bafb4..0b95216c4ce 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/ReferenceDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/ReferenceDto.java @@ -20,15 +20,17 @@ import javax.validation.constraints.Pattern; import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; import de.symeda.sormas.api.audit.AuditIncludeProperty; import de.symeda.sormas.api.audit.AuditedClass; import de.symeda.sormas.api.i18n.Validations; +import de.symeda.sormas.api.utils.HasCaption; import de.symeda.sormas.api.utils.Required; import de.symeda.sormas.api.uuid.HasUuid; @AuditedClass -public abstract class ReferenceDto implements Serializable, HasUuid, Comparable { +public abstract class ReferenceDto implements Serializable, HasUuid, HasCaption, Comparable { public static final String CAPTION = "caption"; public static final String NO_REFERENCE_UUID = "SORMAS-CONSTID-NO-REFERENCE"; @@ -70,10 +72,15 @@ public void setCaption(String caption) { } @Override - public String toString() { + public String buildCaption() { return getCaption(); } + @Override + public String toString() { + return getClass().getSimpleName() + StringUtils.SPACE + this.getUuid(); + } + @Override public boolean equals(Object o) { diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/caze/MapCaseDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/caze/MapCaseDto.java index 9905f1581cd..7dd82286257 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/caze/MapCaseDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/caze/MapCaseDto.java @@ -164,8 +164,8 @@ public void setAddressLon(Double addressLon) { } @Override - public String toString() { - return person.toString() + " (" + DataHelper.getShortUuid(getUuid()) + ")"; + public String buildCaption() { + return person.buildCaption() + " (" + DataHelper.getShortUuid(getUuid()) + ")"; } public Double getHealthFacilityLat() { diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactReferenceDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactReferenceDto.java index f6883c1b0f0..e16b9fea9db 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactReferenceDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactReferenceDto.java @@ -15,8 +15,6 @@ package de.symeda.sormas.api.contact; -import de.symeda.sormas.api.feature.FeatureType; -import de.symeda.sormas.api.utils.DependingOnFeatureType; import java.io.Serializable; import org.apache.commons.lang3.StringUtils; @@ -24,11 +22,14 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import de.symeda.sormas.api.ReferenceDto; +import de.symeda.sormas.api.feature.FeatureType; import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.i18n.Strings; import de.symeda.sormas.api.utils.DataHelper; +import de.symeda.sormas.api.utils.DependingOnFeatureType; import de.symeda.sormas.api.utils.EmbeddedPersonalData; import de.symeda.sormas.api.utils.EmbeddedSensitiveData; +import de.symeda.sormas.api.utils.HasCaption; import de.symeda.sormas.api.utils.PersonalData; import de.symeda.sormas.api.utils.SensitiveData; @@ -130,7 +131,7 @@ public static String buildCaption( return builder.toString(); } - public static class PersonName implements Serializable { + public static class PersonName implements Serializable, HasCaption { private static final long serialVersionUID = 3655299579771996044L; @@ -157,7 +158,7 @@ public String getLastName() { return lastName; } - public String toString() { + public String buildCaption() { return firstName + " " + lastName; } } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/contact/MapContactDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/contact/MapContactDto.java index 45a2c2f6356..41c33b9674d 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/contact/MapContactDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/contact/MapContactDto.java @@ -191,8 +191,7 @@ public void setContactReportDate(Date contactReportDate) { } @Override - public String toString() { - + public String buildCaption() { StringBuilder builder = new StringBuilder(); builder.append(personFirstName).append(" ").append(personLastName.toUpperCase()); if (casePersonFirstName != null && casePersonLastName != null) { diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/dashboard/DashboardEventDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/dashboard/DashboardEventDto.java index 48bccb3a96a..6bef179cde9 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/dashboard/DashboardEventDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/dashboard/DashboardEventDto.java @@ -156,7 +156,7 @@ public DistrictReferenceDto getDistrict() { } @Override - public String toString() { + public String buildCaption() { return EventReferenceDto.buildCaption(getDisease(), getDiseaseDetails(), getEventStatus(), getEventInvestigationStatus(), getEventDate()); } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/event/EventIndexDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/event/EventIndexDto.java index c6f38a67f71..b2a3db43771 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/event/EventIndexDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/event/EventIndexDto.java @@ -24,6 +24,7 @@ import de.symeda.sormas.api.location.LocationReferenceDto; import de.symeda.sormas.api.share.ExternalShareStatus; import de.symeda.sormas.api.user.UserReferenceDto; +import de.symeda.sormas.api.utils.HasCaption; import de.symeda.sormas.api.utils.pseudonymization.PseudonymizableIndexDto; public class EventIndexDto extends PseudonymizableIndexDto { @@ -553,7 +554,7 @@ public boolean getInJurisdictionOrOwned() { return isInJurisdictionOrOwned; } - public static class EventIndexLocation implements Serializable { + public static class EventIndexLocation implements Serializable, HasCaption { private String regionName; private String districtName; @@ -596,8 +597,7 @@ public String getAddress() { return LocationReferenceDto.buildCaption(city, street, houseNumber, additionalInformation); } - @Override - public String toString() { + public String buildCaption() { return LocationReferenceDto.buildCaption(regionName, districtName, communityName, city, street, houseNumber, additionalInformation); } } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/person/JournalPersonDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/person/JournalPersonDto.java index afce5136cb5..e403f2f2f31 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/person/JournalPersonDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/person/JournalPersonDto.java @@ -140,7 +140,7 @@ public void setFollowUpStatus(FollowUpStatus followUpStatus) { } @Override - public String toString() { + public String buildCaption() { return getUuid() + ' ' + firstName + ' ' + lastName; } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/person/SimilarPersonDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/person/SimilarPersonDto.java index fc774c1c6a6..51c9b964d1a 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/person/SimilarPersonDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/person/SimilarPersonDto.java @@ -18,6 +18,8 @@ import java.util.Arrays; import java.util.List; +import com.fasterxml.jackson.annotation.JsonIgnore; + import de.symeda.sormas.api.CountryHelper; import de.symeda.sormas.api.utils.HideForCountries; import de.symeda.sormas.api.uuid.AbstractUuidDto; @@ -194,8 +196,8 @@ public PersonReferenceDto toReference() { return new PersonReferenceDto(getUuid(), firstName, lastName); } - @Override - public String toString() { + @JsonIgnore + public String buildCaption() { return PersonDto.buildCaption(firstName, lastName); } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/utils/DataHelper.java b/sormas-api/src/main/java/de/symeda/sormas/api/utils/DataHelper.java index 42cf760cdc2..a169ad7ad3b 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/utils/DataHelper.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/utils/DataHelper.java @@ -151,6 +151,11 @@ public static String toStringNullable(Object nullable) { if (nullable == null) { return ""; } + + if (HasCaption.class.isAssignableFrom(nullable.getClass())) { + return ((HasCaption) nullable).buildCaption(); + } + return nullable.toString(); } @@ -421,6 +426,8 @@ public static String valueToString(Object value) { } else if (value instanceof BirthDateDto) { BirthDateDto birthDate = (BirthDateDto) value; return DateFormatHelper.formatDate(birthDate.getDateOfBirthDD(), birthDate.getDateOfBirthMM(), birthDate.getDateOfBirthYYYY()); + } else if (value instanceof HasCaption) { + return ((HasCaption) value).buildCaption(); } else { return value.toString(); } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/utils/HasCaption.java b/sormas-api/src/main/java/de/symeda/sormas/api/utils/HasCaption.java new file mode 100644 index 00000000000..74ca5aca90a --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/utils/HasCaption.java @@ -0,0 +1,22 @@ +/* + * SORMAS® - Surveillance Outbreak Response Management & Analysis System + * Copyright © 2016-2022 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package de.symeda.sormas.api.utils; + +public interface HasCaption { + + String buildCaption(); +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/uuid/AbstractUuidDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/uuid/AbstractUuidDto.java index 3e0751bb83e..32593efeee1 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/uuid/AbstractUuidDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/uuid/AbstractUuidDto.java @@ -20,16 +20,21 @@ import javax.validation.constraints.Pattern; import javax.validation.constraints.Size; +import org.apache.commons.lang3.StringUtils; + +import com.fasterxml.jackson.annotation.JsonIgnore; + import de.symeda.sormas.api.audit.AuditIncludeProperty; import de.symeda.sormas.api.audit.AuditedClass; import de.symeda.sormas.api.i18n.Validations; import de.symeda.sormas.api.utils.FieldConstraints; +import de.symeda.sormas.api.utils.HasCaption; /** * An abstract class for all DTOs that have an UUID. */ @AuditedClass -public class AbstractUuidDto implements HasUuid, Serializable { +public class AbstractUuidDto implements HasUuid, HasCaption, Serializable { // FIXME(@JonasCir): I would like to make this class the base class for EntityDto, but there is an @Outbreak annotation // which needs special handling. Also, this should be the base class for ReferenceDto, however, the uuid field there is // required. I argue that the uuid field in this class should be required here as well, however, this would be a big @@ -54,4 +59,14 @@ public String getUuid() { public void setUuid(String uuid) { this.uuid = uuid; } + + @JsonIgnore + public String buildCaption() { + return toString(); + } + + @Override + public String toString() { + return getClass().getSimpleName() + StringUtils.SPACE + this.getUuid(); + } } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/campaign/Campaign.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/campaign/Campaign.java index f6496de07cc..88816a3ff9b 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/campaign/Campaign.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/campaign/Campaign.java @@ -17,6 +17,12 @@ import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_BIG; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.j256.ormlite.field.DataType; +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; + import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Date; @@ -26,12 +32,6 @@ import javax.persistence.Entity; import javax.persistence.Transient; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; -import com.j256.ormlite.field.DataType; -import com.j256.ormlite.field.DatabaseField; -import com.j256.ormlite.table.DatabaseTable; - import de.symeda.sormas.api.campaign.form.CampaignFormMetaReferenceDto; import de.symeda.sormas.app.backend.campaign.form.CampaignFormMeta; import de.symeda.sormas.app.backend.common.DatabaseHelper; @@ -167,7 +167,7 @@ public String getI18nPrefix() { } @Override - public String toString() { + public String buildCaption() { return getName(); } } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/campaign/data/CampaignFormData.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/campaign/data/CampaignFormData.java index dc9119d8a59..0e4bb6b4e46 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/campaign/data/CampaignFormData.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/campaign/data/CampaignFormData.java @@ -200,7 +200,7 @@ public String getI18nPrefix() { } @Override - public String toString() { + public String buildCaption() { return DataHelper.toStringNullable(getCampaign()) + " - " + DataHelper.toStringNullable(getCampaignFormMeta()) + " - " + DataHelper.toStringNullable((getCommunity())) diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/campaign/form/CampaignFormMeta.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/campaign/form/CampaignFormMeta.java index 2ce339d03de..409f2a96171 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/campaign/form/CampaignFormMeta.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/campaign/form/CampaignFormMeta.java @@ -17,6 +17,10 @@ import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_DEFAULT; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.j256.ormlite.table.DatabaseTable; + import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; @@ -25,10 +29,6 @@ import javax.persistence.Entity; import javax.persistence.Transient; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; -import com.j256.ormlite.table.DatabaseTable; - import de.symeda.sormas.api.campaign.form.CampaignFormElement; import de.symeda.sormas.api.campaign.form.CampaignFormTranslations; import de.symeda.sormas.app.backend.common.PseudonymizableAdo; @@ -149,7 +149,7 @@ public String getI18nPrefix() { } @Override - public String toString() { + public String buildCaption() { return getFormName(); } } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/caze/Case.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/caze/Case.java index cf6e2c463f6..a21bdd75078 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/caze/Case.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/caze/Case.java @@ -874,8 +874,8 @@ public boolean isUnreadOrChildUnread() { } @Override - public String toString() { - return super.toString() + " " + (getPerson() != null ? getPerson().toString() : "") + " (" + DataHelper.getShortUuid(getUuid()) + ")"; + public String buildCaption() { + return super.buildCaption() + " " + (getPerson() != null ? getPerson().buildCaption() : "") + " (" + DataHelper.getShortUuid(getUuid()) + ")"; } @Override diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/caze/CaseDao.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/caze/CaseDao.java index b3af658b8e8..7591c112f4f 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/caze/CaseDao.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/caze/CaseDao.java @@ -407,7 +407,7 @@ public Case mergeOrCreate(Case source) throws DaoException { Context context = DatabaseHelper.getContext(); StringBuilder content = new StringBuilder(); - content.append("").append(mergedCase.toString()).append("
"); + content.append("").append(mergedCase.buildCaption()).append("
"); Intent notificationIntent = new Intent(context, CaseReadActivity.class); notificationIntent.putExtras(CaseReadActivity.buildBundle(mergedCase.getUuid(), false).get()); diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/classification/DiseaseClassificationCriteria.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/classification/DiseaseClassificationCriteria.java index 26ad58da022..3fd3c197b22 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/classification/DiseaseClassificationCriteria.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/classification/DiseaseClassificationCriteria.java @@ -15,15 +15,15 @@ package de.symeda.sormas.app.backend.classification; +import com.j256.ormlite.table.DatabaseTable; + +import org.apache.commons.lang3.StringUtils; + import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; -import org.apache.commons.lang3.StringUtils; - -import com.j256.ormlite.table.DatabaseTable; - import de.symeda.sormas.api.Disease; import de.symeda.sormas.app.R; import de.symeda.sormas.app.backend.common.AbstractDomainObject; diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AbstractAdoDao.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AbstractAdoDao.java index 26e6388386a..0fd7dee49db 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AbstractAdoDao.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AbstractAdoDao.java @@ -15,6 +15,19 @@ package de.symeda.sormas.app.backend.common; +import android.util.Log; + +import com.fasterxml.jackson.annotation.JsonRawValue; +import com.googlecode.openbeans.PropertyDescriptor; +import com.j256.ormlite.dao.Dao; +import com.j256.ormlite.dao.GenericRawResults; +import com.j256.ormlite.field.DataType; +import com.j256.ormlite.stmt.QueryBuilder; +import com.j256.ormlite.stmt.Where; +import com.j256.ormlite.support.ConnectionSource; + +import org.apache.commons.lang3.StringUtils; + import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.SQLException; @@ -29,19 +42,6 @@ import javax.persistence.NonUniqueResultException; -import org.apache.commons.lang3.StringUtils; - -import com.fasterxml.jackson.annotation.JsonRawValue; -import com.googlecode.openbeans.PropertyDescriptor; -import com.j256.ormlite.dao.Dao; -import com.j256.ormlite.dao.GenericRawResults; -import com.j256.ormlite.field.DataType; -import com.j256.ormlite.stmt.QueryBuilder; -import com.j256.ormlite.stmt.Where; -import com.j256.ormlite.support.ConnectionSource; - -import android.util.Log; - import de.symeda.sormas.api.ReferenceDto; import de.symeda.sormas.api.feature.FeatureType; import de.symeda.sormas.api.feature.FeatureTypeProperty; @@ -625,7 +625,7 @@ public ADO mergeOrCreate(ADO source) throws DaoException { ADO current = queryUuid(source.getUuid()); ADO snapshot = querySnapshotByUuid(source.getUuid()); - String sourceEntityString = source.toString(); + String sourceEntityString = source.buildCaption(); if (StringUtils.isEmpty(sourceEntityString)) { sourceEntityString = source.getEntityName(); } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AbstractDomainObject.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AbstractDomainObject.java index be413405913..c12f4b340b2 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AbstractDomainObject.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AbstractDomainObject.java @@ -15,6 +15,18 @@ package de.symeda.sormas.app.backend.common; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.databinding.BaseObservable; +import androidx.recyclerview.widget.DiffUtil; + +import com.googlecode.openbeans.PropertyDescriptor; +import com.j256.ormlite.field.DataType; +import com.j256.ormlite.field.DatabaseField; + +import org.apache.commons.lang3.StringUtils; + import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.util.Date; @@ -24,22 +36,12 @@ import javax.persistence.Id; import javax.persistence.MappedSuperclass; -import com.googlecode.openbeans.PropertyDescriptor; -import com.j256.ormlite.field.DataType; -import com.j256.ormlite.field.DatabaseField; - -import android.util.Log; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.databinding.BaseObservable; -import androidx.recyclerview.widget.DiffUtil; - -import de.symeda.sormas.api.uuid.HasUuid; import de.symeda.sormas.api.i18n.I18nProperties; +import de.symeda.sormas.api.utils.HasCaption; +import de.symeda.sormas.api.uuid.HasUuid; @MappedSuperclass -public class AbstractDomainObject extends BaseObservable implements Serializable, Cloneable, HasUuid { +public class AbstractDomainObject extends BaseObservable implements Serializable, Cloneable, HasUuid, HasCaption { public static final String ID = "id"; public static final String UUID = "uuid"; @@ -281,6 +283,11 @@ public void setLastOpenedDate(Date lastOpenedDate) { @Override public String toString() { + return getEntityName() + StringUtils.SPACE + this.getUuid(); + } + + @Override + public String buildCaption() { return getEntityName(); } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AdoDtoHelper.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AdoDtoHelper.java index 8e20df60417..1de312b8277 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AdoDtoHelper.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/AdoDtoHelper.java @@ -15,6 +15,14 @@ package de.symeda.sormas.app.backend.common; +import android.content.Context; +import android.util.Log; + +import com.j256.ormlite.logger.Logger; +import com.j256.ormlite.logger.LoggerFactory; + +import org.springframework.util.CollectionUtils; + import java.io.IOException; import java.sql.SQLException; import java.sql.Timestamp; @@ -25,14 +33,6 @@ import java.util.Optional; import java.util.concurrent.Callable; -import org.springframework.util.CollectionUtils; - -import com.j256.ormlite.logger.Logger; -import com.j256.ormlite.logger.LoggerFactory; - -import android.content.Context; -import android.util.Log; - import de.symeda.sormas.api.EntityDto; import de.symeda.sormas.api.PushResult; import de.symeda.sormas.api.user.UserRight; diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/contact/Contact.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/contact/Contact.java index 60f121b0e30..a28196d66b1 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/contact/Contact.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/contact/Contact.java @@ -18,6 +18,10 @@ import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_BIG; import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_DEFAULT; +import com.j256.ormlite.field.DataType; +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; + import java.util.Date; import javax.persistence.Column; @@ -25,10 +29,6 @@ import javax.persistence.EnumType; import javax.persistence.Enumerated; -import com.j256.ormlite.field.DataType; -import com.j256.ormlite.field.DatabaseField; -import com.j256.ormlite.table.DatabaseTable; - import de.symeda.sormas.api.Disease; import de.symeda.sormas.api.caze.VaccinationStatus; import de.symeda.sormas.api.contact.ContactCategory; @@ -437,8 +437,8 @@ public void setReportLon(Double reportLon) { } @Override - public String toString() { - return super.toString() + " " + (getPerson() != null ? getPerson().toString() : "") + " (" + DataHelper.getShortUuid(getUuid()) + ")"; + public String buildCaption() { + return super.buildCaption() + " " + (getPerson() != null ? getPerson().buildCaption() : "") + " (" + DataHelper.getShortUuid(getUuid()) + ")"; } @Override diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/event/Event.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/event/Event.java index 1cfc453cb57..a3c1832db8a 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/event/Event.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/event/Event.java @@ -661,7 +661,7 @@ public void setWorkEnvironment(WorkEnvironment workEnvironment) { } @Override - public String toString() { + public String buildCaption() { return EventReferenceDto.buildCaption(getDisease(), getDiseaseDetails(), getEventStatus(), getEventInvestigationStatus(), getStartDate()); } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/event/EventParticipant.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/event/EventParticipant.java index 537826ffbc1..148b19bdcc7 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/event/EventParticipant.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/event/EventParticipant.java @@ -17,14 +17,14 @@ import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_DEFAULT; +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; + import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; -import com.j256.ormlite.field.DatabaseField; -import com.j256.ormlite.table.DatabaseTable; - import de.symeda.sormas.api.caze.VaccinationStatus; import de.symeda.sormas.app.backend.common.PseudonymizableAdo; import de.symeda.sormas.app.backend.person.Person; @@ -111,8 +111,8 @@ public void setInvolvementDescription(String involvementDescription) { } @Override - public String toString() { - return getPerson().toString(); + public String buildCaption() { + return getPerson().buildCaption(); } @Override diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/facility/Facility.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/facility/Facility.java index f8bcd32db93..bbc003671cb 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/facility/Facility.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/facility/Facility.java @@ -18,15 +18,15 @@ import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_BIG; import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_DEFAULT; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; +import androidx.databinding.Bindable; import com.j256.ormlite.field.DatabaseField; import com.j256.ormlite.table.DatabaseTable; -import androidx.databinding.Bindable; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; import de.symeda.sormas.api.infrastructure.area.AreaType; import de.symeda.sormas.api.infrastructure.facility.FacilityHelper; @@ -244,7 +244,7 @@ public void setPublicOwnership(boolean publicOwnership) { } @Override - public String toString() { + public String buildCaption() { return FacilityHelper.buildFacilityString(getUuid(), name); } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/hospitalization/PreviousHospitalization.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/hospitalization/PreviousHospitalization.java index af602f7f122..e5078459945 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/hospitalization/PreviousHospitalization.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/hospitalization/PreviousHospitalization.java @@ -18,6 +18,10 @@ import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_BIG; import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_DEFAULT; +import com.j256.ormlite.field.DataType; +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; + import java.util.Date; import javax.persistence.Column; @@ -25,10 +29,6 @@ import javax.persistence.EnumType; import javax.persistence.Enumerated; -import com.j256.ormlite.field.DataType; -import com.j256.ormlite.field.DatabaseField; -import com.j256.ormlite.table.DatabaseTable; - import de.symeda.sormas.api.hospitalization.HospitalizationReasonType; import de.symeda.sormas.api.utils.YesNoUnknown; import de.symeda.sormas.app.backend.common.EmbeddedAdo; @@ -247,7 +247,7 @@ public String getI18nPrefix() { } @Override - public String toString() { - return super.toString() + " " + DateFormatHelper.formatLocalDate(getDischargeDate()); + public String buildCaption() { + return super.buildCaption() + " " + DateFormatHelper.formatLocalDate(getDischargeDate()); } } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/immunization/ImmunizationDtoHelper.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/immunization/ImmunizationDtoHelper.java index dfcf736bcd7..abeae07f9f2 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/immunization/ImmunizationDtoHelper.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/immunization/ImmunizationDtoHelper.java @@ -215,7 +215,7 @@ public static ImmunizationReferenceDto toReferenceDto(Immunization ado) { if (ado == null) { return null; } - ImmunizationReferenceDto dto = new ImmunizationReferenceDto(ado.getUuid(), ado.toString(), ado.getExternalId()); + ImmunizationReferenceDto dto = new ImmunizationReferenceDto(ado.getUuid(), ado.buildCaption(), ado.getExternalId()); return dto; } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/infrastructure/PointOfEntry.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/infrastructure/PointOfEntry.java index 4301f5227f3..5124588f94b 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/infrastructure/PointOfEntry.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/infrastructure/PointOfEntry.java @@ -15,14 +15,14 @@ package de.symeda.sormas.app.backend.infrastructure; +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; + import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; -import com.j256.ormlite.field.DatabaseField; -import com.j256.ormlite.table.DatabaseTable; - import de.symeda.sormas.api.infrastructure.InfrastructureHelper; import de.symeda.sormas.api.infrastructure.pointofentry.PointOfEntryType; import de.symeda.sormas.app.backend.common.InfrastructureAdo; @@ -123,7 +123,7 @@ public String getI18nPrefix() { } @Override - public String toString() { + public String buildCaption() { return InfrastructureHelper.buildPointOfEntryString(getUuid(), name); } } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/location/Location.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/location/Location.java index b716ba6ad01..0b5e79487b8 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/location/Location.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/location/Location.java @@ -18,17 +18,17 @@ import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_BIG; import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_DEFAULT; -import java.text.DecimalFormat; +import androidx.databinding.Bindable; -import javax.persistence.Column; -import javax.persistence.Entity; +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; import org.apache.commons.lang3.StringUtils; -import com.j256.ormlite.field.DatabaseField; -import com.j256.ormlite.table.DatabaseTable; +import java.text.DecimalFormat; -import androidx.databinding.Bindable; +import javax.persistence.Column; +import javax.persistence.Entity; import de.symeda.sormas.api.infrastructure.area.AreaType; import de.symeda.sormas.api.infrastructure.facility.FacilityType; @@ -353,13 +353,13 @@ public String getCompleteString() { if (getCity() != null && !getCity().isEmpty()) { sb.append(getCity()); } else if (getCommunity() != null) { - sb.append(getCommunity()); + sb.append(getCommunity().buildCaption()); } if (getDistrict() != null) { if (sb.length() > 0) { sb.append(", "); } - sb.append(getDistrict()); + sb.append(getDistrict().buildCaption()); } if (getAreaType() != null) { if (sb.length() > 0) { @@ -443,7 +443,7 @@ public static String getLatLonString(Double latitude, Double longitude, Float la } @Override - public String toString() { + public String buildCaption() { return getCompleteString(); } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/person/Person.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/person/Person.java index 46458077d61..c193ca5704b 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/person/Person.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/person/Person.java @@ -17,6 +17,14 @@ import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_DEFAULT; +import androidx.databinding.Bindable; + +import com.j256.ormlite.field.DataType; +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; + +import org.apache.commons.lang3.StringUtils; + import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -27,14 +35,6 @@ import javax.persistence.Enumerated; import javax.persistence.Transient; -import org.apache.commons.lang3.StringUtils; - -import com.j256.ormlite.field.DataType; -import com.j256.ormlite.field.DatabaseField; -import com.j256.ormlite.table.DatabaseTable; - -import androidx.databinding.Bindable; - import de.symeda.sormas.api.Disease; import de.symeda.sormas.api.customizableenum.CustomizableEnumType; import de.symeda.sormas.api.infrastructure.facility.FacilityType; @@ -436,7 +436,7 @@ public void setCauseOfDeathDisease(Disease causeOfDeathDisease) { } @Override - public String toString() { + public String buildCaption() { StringBuilder builder = new StringBuilder(); builder.append(getFirstName() != null ? getFirstName() : "").append(" ").append((getLastName() != null ? getLastName() : "").toUpperCase()); return builder.toString(); diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/person/PersonContactDetail.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/person/PersonContactDetail.java index f267f9faec5..24b53325f83 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/person/PersonContactDetail.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/person/PersonContactDetail.java @@ -82,7 +82,7 @@ public String getOwner() { } public String getOwnerName() { - return isThirdParty() ? getThirdPartyName() : person.toString(); + return isThirdParty() ? getThirdPartyName() : person.buildCaption(); } public Person getPerson() { diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Area.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Area.java index 493593e031b..c7ac8c6ec2e 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Area.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Area.java @@ -57,7 +57,7 @@ public void setExternalId(String externalId) { } @Override - public String toString() { + public String buildCaption() { return getName(); } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Community.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Community.java index aad91cc21e3..78e382a1505 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Community.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Community.java @@ -15,15 +15,15 @@ package de.symeda.sormas.app.backend.region; +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; + import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; -import com.j256.ormlite.field.DatabaseField; -import com.j256.ormlite.table.DatabaseTable; - import de.symeda.sormas.app.backend.common.InfrastructureAdo; @Entity(name = Community.TABLE_NAME) @@ -63,7 +63,7 @@ public void setDistrict(District district) { } @Override - public String toString() { + public String buildCaption() { return getName(); } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Continent.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Continent.java index bf1440cf341..2fc9b8db782 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Continent.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Continent.java @@ -46,7 +46,7 @@ public void setDefaultName(String defaultName) { } @Override - public String toString() { + public String buildCaption() { return getDefaultName(); } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Country.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Country.java index ec6dfc29fac..4ef7615dce2 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Country.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Country.java @@ -60,7 +60,7 @@ public void setSubcontinent(Subcontinent subcontinent) { } @Override - public String toString() { + public String buildCaption() { return getName(); } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/District.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/District.java index f8056e808ac..3589ded8708 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/District.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/District.java @@ -82,7 +82,7 @@ public void setRegion(Region region) { } @Override - public String toString() { + public String buildCaption() { return getName(); } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Region.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Region.java index 9b978b6f020..14116fc1c76 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Region.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Region.java @@ -89,7 +89,7 @@ public void setCountry(Country country) { } @Override - public String toString() { + public String buildCaption() { return getName(); } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Subcontinent.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Subcontinent.java index 3cef5af28cc..990dd0c4ab6 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Subcontinent.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/region/Subcontinent.java @@ -15,15 +15,15 @@ package de.symeda.sormas.app.backend.region; +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; + import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; -import com.j256.ormlite.field.DatabaseField; -import com.j256.ormlite.table.DatabaseTable; - import de.symeda.sormas.app.backend.common.InfrastructureAdo; @Entity(name = Subcontinent.TABLE_NAME) @@ -61,7 +61,7 @@ public void setContinent(Continent continent) { } @Override - public String toString() { + public String buildCaption() { return getDefaultName(); } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/sample/PathogenTest.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/sample/PathogenTest.java index 31e57779ab7..f3bbf6c6f45 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/sample/PathogenTest.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/sample/PathogenTest.java @@ -18,6 +18,12 @@ import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_BIG; import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_DEFAULT; +import com.j256.ormlite.field.DataType; +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; + +import org.apache.commons.lang3.StringUtils; + import java.util.Date; import javax.persistence.Column; @@ -26,12 +32,6 @@ import javax.persistence.Enumerated; import javax.persistence.Transient; -import org.apache.commons.lang3.StringUtils; - -import com.j256.ormlite.field.DataType; -import com.j256.ormlite.field.DatabaseField; -import com.j256.ormlite.table.DatabaseTable; - import de.symeda.sormas.api.Disease; import de.symeda.sormas.api.customizableenum.CustomizableEnumType; import de.symeda.sormas.api.disease.DiseaseVariant; @@ -313,7 +313,7 @@ public String getI18nPrefix() { } @Override - public String toString() { - return super.toString() + DateFormatHelper.formatLocalDate(getTestDateTime()); + public String buildCaption() { + return super.buildCaption() + DateFormatHelper.formatLocalDate(getTestDateTime()); } } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/sample/Sample.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/sample/Sample.java index da2915997f5..90824c57bf8 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/sample/Sample.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/sample/Sample.java @@ -18,6 +18,12 @@ import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_BIG; import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_DEFAULT; +import com.j256.ormlite.field.DataType; +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; + +import org.apache.commons.lang3.StringUtils; + import java.util.Date; import java.util.HashSet; import java.util.Set; @@ -28,12 +34,6 @@ import javax.persistence.Enumerated; import javax.persistence.Transient; -import org.apache.commons.lang3.StringUtils; - -import com.j256.ormlite.field.DataType; -import com.j256.ormlite.field.DatabaseField; -import com.j256.ormlite.table.DatabaseTable; - import de.symeda.sormas.api.sample.AdditionalTestType; import de.symeda.sormas.api.sample.PathogenTestResultType; import de.symeda.sormas.api.sample.PathogenTestType; @@ -494,8 +494,8 @@ public String getI18nPrefix() { } @Override - public String toString() { - return super.toString() + " " + DateFormatHelper.formatLocalDate(getSampleDateTime()); + public String buildCaption() { + return super.buildCaption() + " " + DateFormatHelper.formatLocalDate(getSampleDateTime()); } public Double getReportLat() { diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/user/User.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/user/User.java index 2f97e67d70d..7f0624b5a65 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/user/User.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/user/User.java @@ -15,6 +15,9 @@ package de.symeda.sormas.app.backend.user; +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; + import java.util.Arrays; import java.util.Set; @@ -23,9 +26,6 @@ import javax.persistence.EnumType; import javax.persistence.Enumerated; -import com.j256.ormlite.field.DatabaseField; -import com.j256.ormlite.table.DatabaseTable; - import de.symeda.sormas.api.Disease; import de.symeda.sormas.api.Language; import de.symeda.sormas.api.user.JurisdictionLevel; @@ -266,7 +266,7 @@ public boolean hasJurisdictionLevel(JurisdictionLevel... jurisdictionLevels) { } @Override - public String toString() { + public String buildCaption() { StringBuilder result = new StringBuilder(); result.append(getFirstName()).append(" ").append(getLastName().toUpperCase()); diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/visit/Visit.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/visit/Visit.java index d6c730835ba..2e7d0278c81 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/visit/Visit.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/visit/Visit.java @@ -17,6 +17,10 @@ import static de.symeda.sormas.api.utils.FieldConstraints.CHARACTER_LIMIT_DEFAULT; +import com.j256.ormlite.field.DataType; +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; + import java.util.Date; import javax.persistence.Column; @@ -24,10 +28,6 @@ import javax.persistence.EnumType; import javax.persistence.Enumerated; -import com.j256.ormlite.field.DataType; -import com.j256.ormlite.field.DatabaseField; -import com.j256.ormlite.table.DatabaseTable; - import de.symeda.sormas.api.Disease; import de.symeda.sormas.api.VisitOrigin; import de.symeda.sormas.api.visit.VisitStatus; @@ -175,8 +175,8 @@ public String getI18nPrefix() { } @Override - public String toString() { - return super.toString() + " " + DateFormatHelper.formatLocalDate(getVisitDateTime()); + public String buildCaption() { + return super.buildCaption() + " " + DateFormatHelper.formatLocalDate(getVisitDateTime()); } public Float getReportLatLonAccuracy() { diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/component/controls/ControlTextReadField.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/component/controls/ControlTextReadField.java index 7386ccfbdf6..d94d07a0883 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/component/controls/ControlTextReadField.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/component/controls/ControlTextReadField.java @@ -15,12 +15,6 @@ package de.symeda.sormas.app.component.controls; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Date; - -import org.apache.commons.lang3.StringUtils; - import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; @@ -36,6 +30,12 @@ import androidx.databinding.BindingMethods; import androidx.databinding.InverseBindingListener; +import org.apache.commons.lang3.StringUtils; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Date; + import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.person.ApproximateAgeType; import de.symeda.sormas.api.symptoms.SymptomsDto; @@ -336,7 +336,7 @@ public static void setValue( String appendValue, String valueFormat, String defaultValue) { - setValue(textField, ado != null ? ado.toString() : null, appendValue, valueFormat, defaultValue, ado); + setValue(textField, ado != null ? ado.buildCaption() : null, appendValue, valueFormat, defaultValue, ado); } // Date & date range diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/core/TaskNotificationService.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/core/TaskNotificationService.java index 63eda2180c5..6f3c41cf902 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/core/TaskNotificationService.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/core/TaskNotificationService.java @@ -15,9 +15,6 @@ package de.symeda.sormas.app.core; -import java.util.Date; -import java.util.List; - import android.app.AlarmManager; import android.app.NotificationManager; import android.app.PendingIntent; @@ -32,6 +29,9 @@ import androidx.core.app.NotificationCompat; +import java.util.Date; +import java.util.List; + import de.symeda.sormas.api.feature.FeatureType; import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.api.utils.DateHelper; @@ -124,21 +124,21 @@ public static void doTaskNotification(Context context) { if (task.getCaze() != null && !DatabaseHelper.getFeatureConfigurationDao().isFeatureDisabled(FeatureType.TASK_GENERATION_CASE_SURVEILLANCE)) { caze = caseDAO.queryForId(task.getCaze().getId()); - content.append("").append(caze.toString()).append("
"); + content.append("").append(caze.buildCaption()).append("
"); } break; case CONTACT: if (task.getContact() != null && !DatabaseHelper.getFeatureConfigurationDao().isFeatureDisabled(FeatureType.TASK_GENERATION_CONTACT_TRACING)) { contact = contactDAO.queryForId(task.getContact().getId()); - content.append("").append(contact.toString()).append("
"); + content.append("").append(contact.buildCaption()).append("
"); } break; case EVENT: if (task.getEvent() != null && !DatabaseHelper.getFeatureConfigurationDao().isFeatureDisabled(FeatureType.TASK_GENERATION_EVENT_SURVEILLANCE)) { event = eventDAO.queryForId(task.getEvent().getId()); - content.append("").append(event.toString()).append("
"); + content.append("").append(event.buildCaption()).append("
"); } break; case GENERAL: diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/report/aggregate/AggregateReportsFragment.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/report/aggregate/AggregateReportsFragment.java index cfc03d911c9..cd54f8b9f1f 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/report/aggregate/AggregateReportsFragment.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/report/aggregate/AggregateReportsFragment.java @@ -611,7 +611,7 @@ public ReportUserInfo(User user, District district, Facility facility, PointOfEn public String getCaption() { - return getInfrastructure().toString() + (user != null ? " - " + user.getUserName() : ""); + return getInfrastructure().buildCaption() + (user != null ? " - " + user.getUserName() : ""); } public boolean isCurrentUserReport() { diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/settings/SettingsFragment.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/settings/SettingsFragment.java index 18b94f17f87..ac66cad5939 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/settings/SettingsFragment.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/settings/SettingsFragment.java @@ -226,43 +226,43 @@ public void call() { for (Case caze : modifiedCases) { if (DatabaseHelper.getCaseDao().queryUuidReference(caze.getUuid()) == null) { DatabaseHelper.getSyncLogDao() - .createWithParentStack(caze.toString(), getResources().getString(R.string.caption_changed_data_lost)); + .createWithParentStack(caze.buildCaption(), getResources().getString(R.string.caption_changed_data_lost)); } } for (Contact contact : modifiedContacts) { if (DatabaseHelper.getContactDao().queryUuidReference(contact.getUuid()) == null) { DatabaseHelper.getSyncLogDao() - .createWithParentStack(contact.toString(), getResources().getString(R.string.caption_changed_data_lost)); + .createWithParentStack(contact.buildCaption(), getResources().getString(R.string.caption_changed_data_lost)); } } for (Person person : modifiedPersons) { if (DatabaseHelper.getPersonDao().queryUuidReference(person.getUuid()) == null) { DatabaseHelper.getSyncLogDao() - .createWithParentStack(person.toString(), getResources().getString(R.string.caption_changed_data_lost)); + .createWithParentStack(person.buildCaption(), getResources().getString(R.string.caption_changed_data_lost)); } } for (Event event : modifiedEvents) { if (DatabaseHelper.getEventDao().queryUuidReference(event.getUuid()) == null) { DatabaseHelper.getSyncLogDao() - .createWithParentStack(event.toString(), getResources().getString(R.string.caption_changed_data_lost)); + .createWithParentStack(event.buildCaption(), getResources().getString(R.string.caption_changed_data_lost)); } } for (EventParticipant eventParticipant : modifiedEventParticipants) { if (DatabaseHelper.getEventParticipantDao().queryUuidReference(eventParticipant.getUuid()) == null) { DatabaseHelper.getSyncLogDao() - .createWithParentStack(eventParticipant.toString(), getResources().getString(R.string.caption_changed_data_lost)); + .createWithParentStack(eventParticipant.buildCaption(), getResources().getString(R.string.caption_changed_data_lost)); } } for (Sample sample : modifiedSamples) { if (DatabaseHelper.getSampleDao().queryUuidReference(sample.getUuid()) == null) { DatabaseHelper.getSyncLogDao() - .createWithParentStack(sample.toString(), getResources().getString(R.string.caption_changed_data_lost)); + .createWithParentStack(sample.buildCaption(), getResources().getString(R.string.caption_changed_data_lost)); } } for (Visit visit : modifiedVisits) { if (DatabaseHelper.getVisitDao().queryUuidReference(visit.getUuid()) == null) { DatabaseHelper.getSyncLogDao() - .createWithParentStack(visit.toString(), getResources().getString(R.string.caption_changed_data_lost)); + .createWithParentStack(visit.buildCaption(), getResources().getString(R.string.caption_changed_data_lost)); } } } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/util/DataUtils.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/util/DataUtils.java index f47b7cccf34..78e1b6c4766 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/util/DataUtils.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/util/DataUtils.java @@ -27,6 +27,7 @@ import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; import de.symeda.sormas.app.R; +import de.symeda.sormas.app.backend.common.AbstractDomainObject; import de.symeda.sormas.app.backend.common.DatabaseHelper; import de.symeda.sormas.app.component.Item; import de.symeda.sormas.app.component.controls.ControlSpinnerField; @@ -79,7 +80,6 @@ public static boolean emptyOrWithOneNullItem(List listIn) { return listIn.isEmpty() || (listIn.size() == 1 && (listIn.get(0) == null || listIn.get(0).getValue() == null)); } - public static List toItems(List listIn) { return toItems(listIn, true); } @@ -115,7 +115,12 @@ public static List toItems(List listIn, boolean withNull) { } if (listIn != null) { for (E listInEntry : listIn) { - listOut.add(new Item(String.valueOf(listInEntry), listInEntry)); + listOut.add( + new Item( + listInEntry instanceof AbstractDomainObject + ? ((AbstractDomainObject) listInEntry).buildCaption() + : String.valueOf(listInEntry), + listInEntry)); } } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/util/FormBindingAdapters.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/util/FormBindingAdapters.java index 616a949e6c7..197ae9dd8f5 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/util/FormBindingAdapters.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/util/FormBindingAdapters.java @@ -17,8 +17,6 @@ import static android.view.View.GONE; -import java.util.List; - import android.content.Context; import android.graphics.drawable.Drawable; import android.util.TypedValue; @@ -31,6 +29,8 @@ import androidx.core.content.ContextCompat; import androidx.databinding.BindingAdapter; +import java.util.List; + import de.symeda.sormas.api.sample.PathogenTestResultType; import de.symeda.sormas.api.symptoms.SymptomState; import de.symeda.sormas.api.user.UserRight; @@ -72,9 +72,9 @@ public static void setCazeAndLocation(ControlLinkField control, Case caze, Strin } else { String location = ""; if (caze.getPerson() != null && caze.getPerson().getAddress() != null) { - location = "\n" + caze.getPerson().getAddress().toString(); + location = "\n" + caze.getPerson().getAddress().buildCaption(); } - val = caze.toString() + location; + val = caze.buildCaption() + location; if (valueFormat != null && valueFormat.trim() != "") { control.setValue(String.format(valueFormat, val)); @@ -96,9 +96,9 @@ public static void setContactAndLocation(ControlLinkField control, Contact conta } else { String location = ""; if (contact.getPerson() != null && contact.getPerson().getAddress() != null) { - location = "\n" + contact.getPerson().getAddress().toString(); + location = "\n" + contact.getPerson().getAddress().buildCaption(); } - val = contact.toString() + location; + val = contact.buildCaption() + location; if (valueFormat != null && valueFormat.trim() != "") { control.setValue(String.format(valueFormat, val)); @@ -120,9 +120,9 @@ public static void setEventAndLocation(ControlLinkField control, Event event, St } else { String location = ""; if (event.getEventLocation() != null) { - location = "\n" + event.getEventLocation().toString(); + location = "\n" + event.getEventLocation().buildCaption(); } - val = event.toString() + location; + val = event.buildCaption() + location; if (valueFormat != null && valueFormat.trim() != "") { control.setValue(String.format(valueFormat, val)); @@ -213,7 +213,7 @@ public static void setLocationValue(ControlLinkField textField, Location locatio if (location == null) { textField.setValue(val); } else { - val = location.toString(); + val = location.buildCaption(); if (valueFormat != null && valueFormat.trim() != "") { textField.setValue(String.format(valueFormat, val)); diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/util/TextViewBindingAdapters.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/util/TextViewBindingAdapters.java index 4ca3f9bc10e..7a9df84981b 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/util/TextViewBindingAdapters.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/util/TextViewBindingAdapters.java @@ -17,14 +17,6 @@ import static android.view.View.VISIBLE; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.lang3.StringUtils; - import android.content.Context; import android.content.res.Resources; import android.graphics.Typeface; @@ -38,6 +30,14 @@ import androidx.databinding.BindingAdapter; import androidx.databinding.ObservableList; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import de.symeda.sormas.api.Disease; import de.symeda.sormas.api.caze.InvestigationStatus; import de.symeda.sormas.api.i18n.I18nProperties; @@ -254,7 +254,7 @@ public static void setLocationValueWithPrepend( String defaultValue) { String val = defaultValue; - if (location == null || location.toString().isEmpty()) { + if (location == null || location.buildCaption().isEmpty()) { textField.setText(prependValue + ": " + val); } else { val = location.getCompleteString(); @@ -265,7 +265,7 @@ public static void setLocationValueWithPrepend( textField.setText(prependValue + ": " + val); } - textField.setText(location.toString()); + textField.setText(location.buildCaption()); } } @@ -658,7 +658,7 @@ public static void setUserValue(TextView textField, User user, String defaultVal if (valueFormat != null && valueFormat.trim() != "") { textField.setText(String.format(valueFormat, user.getFirstName(), user.getLastName().toUpperCase())); } else { - textField.setText(user.toString()); + textField.setText(user.buildCaption()); } } } @@ -680,7 +680,7 @@ public static void setPersonValue(TextView textField, Person person, String defa if (valueFormat != null && !valueFormat.trim().equals("")) { textField.setText(String.format(valueFormat, person.getFirstName(), person.getLastName())); } else { - textField.setText(person.toString()); + textField.setText(person.buildCaption()); } } } @@ -943,10 +943,10 @@ public static void setTimeAgoValue(TextView textField, Date dateValue, boolean t "shortLocationValue", "defaultValue" }, requireAll = false) public static void setShortLocationValue(TextView textField, Location location, String defaultValue) { - if (location == null || location.toString().isEmpty()) { + if (location == null || location.buildCaption().isEmpty()) { textField.setText(defaultValue); } else { - textField.setText(location.getRegion() + ", " + location.getDistrict()); + textField.setText(location.getRegion().buildCaption() + ", " + location.getDistrict().buildCaption()); } } @@ -954,10 +954,10 @@ public static void setShortLocationValue(TextView textField, Location location, "locationValue", "defaultValue" }, requireAll = false) public static void setLocationValue(TextView textField, Location location, String defaultValue) { - if (location == null || location.toString().isEmpty()) { + if (location == null || location.buildCaption().isEmpty()) { textField.setText(defaultValue); } else { - textField.setText(location.toString()); + textField.setText(location.buildCaption()); } } @@ -1000,7 +1000,7 @@ public static void setFacilityValue(TextView textField, Facility facility, Strin if (facility == null) { textField.setText(defaultValue); } else { - textField.setText(facility.toString()); + textField.setText(facility.buildCaption()); } } @@ -1042,7 +1042,7 @@ public static void setPointOfEntryValue(TextView textField, PointOfEntry pointOf if (pointOfEntry == null) { textField.setText(defaultValue); } else { - textField.setText(pointOfEntry.toString()); + textField.setText(pointOfEntry.buildCaption()); } } @@ -1050,10 +1050,10 @@ public static void setPointOfEntryValue(TextView textField, PointOfEntry pointOf "adoValue", "defaultValue" }, requireAll = false) public static void setAdoValue(TextView textField, AbstractDomainObject ado, String defaultValue) { - if (ado == null || StringUtils.isEmpty(ado.toString())) { + if (ado == null || StringUtils.isEmpty(ado.buildCaption())) { textField.setText(defaultValue); } else { - textField.setText(ado.toString()); + textField.setText(ado.buildCaption()); } } @@ -1161,7 +1161,7 @@ private static String getPersonInfo(Sample sample) { if (person == null) return result; - return person.toString(); + return person.buildCaption(); } private static String getPersonInfo(Task record) { diff --git a/sormas-app/app/src/main/res/layout/fragment_task_edit_layout.xml b/sormas-app/app/src/main/res/layout/fragment_task_edit_layout.xml index 70f8493c95e..dca537dfc1c 100644 --- a/sormas-app/app/src/main/res/layout/fragment_task_edit_layout.xml +++ b/sormas-app/app/src/main/res/layout/fragment_task_edit_layout.xml @@ -60,19 +60,19 @@ android:id="@+id/task_caze" style="@style/ControlSingleColumnStyle" app:goneIfEmpty="@{data.caze}" - app:value="@{data.caze.toString()}" /> + app:value="@{data.caze.buildCaption()}" /> + app:value="@{data.contact.buildCaption()}" /> + app:value="@{data.event.buildCaption()}" /> getAllCampaignFormMetasAsReferences() return service.getAll() .stream() .map(CampaignFormMetaFacadeEjb::toReferenceDto) - .sorted(Comparator.comparing(ReferenceDto::toString)) + .sorted(Comparator.comparing(ReferenceDto::buildCaption)) .collect(Collectors.toList()); } 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 90e2c3a6a27..074b43765b1 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 @@ -217,7 +217,7 @@ public UserDto createUser(RDCF rdcf, UserRoleReferenceDto userRole, Consumer campagaignFormReferences = FacadeProvider.getCampaignFormMetaFacade().getCampaignFormMetasAsReferencesByCampaign(campaignReferenceDto.getUuid()); for (CampaignFormMetaReferenceDto campaignForm : campagaignFormReferences) { - Button campaignFormButton = ButtonHelper.createButton(campaignForm.toString(), e -> { + Button campaignFormButton = ButtonHelper.createButton(campaignForm.buildCaption(), e -> { importCampaignButton.setPopupVisible(false); try { Window popupWindow = VaadinUiUtil.showPopupWindow(new CampaignFormDataImportLayout(campaignForm, campaignReferenceDto)); @@ -236,7 +236,7 @@ private void fillNewFormDropdown(Panel containerPanel) { List campagaignFormReferences = FacadeProvider.getCampaignFormMetaFacade().getCampaignFormMetasAsReferencesByCampaign(campaignReferenceDto.getUuid()); for (CampaignFormMetaReferenceDto campaignForm : campagaignFormReferences) { - Button campaignFormButton = ButtonHelper.createButton(campaignForm.toString(), e -> { + Button campaignFormButton = ButtonHelper.createButton(campaignForm.buildCaption(), e -> { ControllerProvider.getCampaignController().createCampaignDataForm(criteria.getCampaign(), campaignForm); newFormButton.setPopupVisible(false); }); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigndata/CampaignFormDataSelectionField.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigndata/CampaignFormDataSelectionField.java index e538d52a95b..30b8e3f9f17 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigndata/CampaignFormDataSelectionField.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigndata/CampaignFormDataSelectionField.java @@ -119,17 +119,17 @@ private HorizontalLayout buildFormDataDetailsComponent(CampaignFormDataDto formD HorizontalLayout formDataLayout = new HorizontalLayout(); formDataLayout.setSpacing(true); { - Label fdRegion = new Label(formData.getRegion() != null ? formData.getRegion().toString() : ""); + Label fdRegion = new Label(formData.getRegion() != null ? formData.getRegion().buildCaption() : ""); fdRegion.setCaption(I18nProperties.getPrefixCaption(CampaignFormDataDto.I18N_PREFIX, CampaignFormDataDto.REGION)); fdRegion.setWidthUndefined(); formDataLayout.addComponent(fdRegion); - Label fdDistrict = new Label(formData.getDistrict() != null ? formData.getDistrict().toString() : ""); + Label fdDistrict = new Label(formData.getDistrict() != null ? formData.getDistrict().buildCaption() : ""); fdDistrict.setCaption(I18nProperties.getPrefixCaption(CampaignFormDataDto.I18N_PREFIX, CampaignFormDataDto.DISTRICT)); fdDistrict.setWidthUndefined(); formDataLayout.addComponent(fdDistrict); - Label fdCommunity = new Label(formData.getCommunity() != null ? formData.getCommunity().toString() : ""); + Label fdCommunity = new Label(formData.getCommunity() != null ? formData.getCommunity().buildCaption() : ""); fdCommunity.setCaption(I18nProperties.getPrefixCaption(CampaignFormDataDto.I18N_PREFIX, CampaignFormDataDto.COMMUNITY)); fdCommunity.setWidthUndefined(); formDataLayout.addComponent(fdCommunity); @@ -140,7 +140,7 @@ private HorizontalLayout buildFormDataDetailsComponent(CampaignFormDataDto formD formDataLayout.addComponent(fdFormDate); if (existingData) { - Label fdCreatingUser = new Label(formData.getCreatingUser() != null ? formData.getCreatingUser().toString() : ""); + Label fdCreatingUser = new Label(formData.getCreatingUser() != null ? formData.getCreatingUser().buildCaption() : ""); fdCreatingUser.setCaption(I18nProperties.getPrefixCaption(CampaignFormDataDto.I18N_PREFIX, CampaignFormDataDto.CREATING_USER)); fdCreatingUser.setWidthUndefined(); formDataLayout.addComponent(fdCreatingUser); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigndata/CampaignFormDataView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigndata/CampaignFormDataView.java index d285785129e..ef45d15b7d7 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigndata/CampaignFormDataView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigndata/CampaignFormDataView.java @@ -59,7 +59,7 @@ protected void initView(String params) { () -> { SormasUI.refreshView(); Notification.show( - String.format(I18nProperties.getString(Strings.messageCampaignFormSaved), campaignFormData.getCampaignFormMeta().toString()), + String.format(I18nProperties.getString(Strings.messageCampaignFormSaved), campaignFormData.getCampaignFormMeta().buildCaption()), TRAY_NOTIFICATION); }, null); @@ -71,6 +71,6 @@ protected void initView(String params) { container.addComponent(editComponent); - getViewTitleLabel().setValue(campaignFormData.getCampaignFormMeta().toString()); + getViewTitleLabel().setValue(campaignFormData.getCampaignFormMeta().buildCaption()); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigns/CampaignFormsGridComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigns/CampaignFormsGridComponent.java index df06e116b52..37696975b41 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigns/CampaignFormsGridComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/campaigns/CampaignFormsGridComponent.java @@ -2,7 +2,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.UUID; import com.vaadin.data.Binder; import com.vaadin.ui.Button; diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/components/CampaignSelector.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/components/CampaignSelector.java index ca85f5ea284..ca1341553bf 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/components/CampaignSelector.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/components/CampaignSelector.java @@ -31,6 +31,7 @@ public CampaignSelector() { campaignCombo = new ComboBox<>(" "); List campaigns = FacadeProvider.getCampaignFacade().getAllActiveCampaignsAsReference(); campaignCombo.setItems(campaigns); + campaignCombo.setItemCaptionGenerator(item -> item.buildCaption()); campaignCombo.setEmptySelectionCaption(I18nProperties.getCaption(Captions.campaignAllCampaigns)); final CampaignReferenceDto lastStartedCampaign = FacadeProvider.getCampaignFacade().getLastStartedCampaign(); if (lastStartedCampaign != null) { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/importer/CampaignFormDataImporter.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/importer/CampaignFormDataImporter.java index f9c8cce7a95..abcd983ad90 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/importer/CampaignFormDataImporter.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/campaign/importer/CampaignFormDataImporter.java @@ -328,8 +328,8 @@ private void handleDetectedDuplicate(CampaignFormDataDto newData, CampaignFormDa existingData, String.format( I18nProperties.getString(Strings.infoSkipOrOverrideDuplicateCampaignFormDataImport), - newData.getCampaign().toString(), - newData.getCampaignFormMeta().toString()), + newData.getCampaign().buildCaption(), + newData.getCampaignFormMeta().buildCaption()), cancelCallback, skipCallback, overwriteCallback); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseInfoLayout.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseInfoLayout.java index acf25487ddc..0f241fb934c 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseInfoLayout.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseInfoLayout.java @@ -105,7 +105,7 @@ private void updateCaseInfo() { addDescLabel( leftColumnLayout, CaseDataDto.PERSON, - caseDto.getPerson(), + caseDto.getPerson().buildCaption(), I18nProperties.getPrefixCaption(CaseDataDto.I18N_PREFIX, CaseDataDto.PERSON)); HorizontalLayout ageSexLayout = new HorizontalLayout(); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasePickOrCreateField.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasePickOrCreateField.java index 42f4c846581..325ca687485 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasePickOrCreateField.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasePickOrCreateField.java @@ -108,14 +108,14 @@ protected void addInfoComponent() { Label responsibleDistrictField = new Label(); responsibleDistrictField.setCaption(I18nProperties.getPrefixCaption(CaseDataDto.I18N_PREFIX, CaseDataDto.RESPONSIBLE_DISTRICT)); - responsibleDistrictField.setValue(newCase.getResponsibleDistrict() != null ? newCase.getResponsibleDistrict().toString() : ""); + responsibleDistrictField.setValue(newCase.getResponsibleDistrict() != null ? newCase.getResponsibleDistrict().buildCaption() : ""); responsibleDistrictField.setWidthUndefined(); caseInfoLayout.addComponent(responsibleDistrictField); if (newCase.getDistrict() != null) { Label districtField = new Label(); districtField.setCaption(I18nProperties.getPrefixCaption(CaseDataDto.I18N_PREFIX, CaseDataDto.DISTRICT)); - districtField.setValue(newCase.getDistrict().toString()); + districtField.setValue(newCase.getDistrict().buildCaption()); districtField.setWidthUndefined(); caseInfoLayout.addComponent(districtField); } @@ -125,7 +125,7 @@ protected void addInfoComponent() { facilityField.setValue( FacilityHelper.buildFacilityString( null, - newCase.getHealthFacility() != null ? newCase.getHealthFacility().toString() : "", + newCase.getHealthFacility() != null ? newCase.getHealthFacility().buildCaption() : "", newCase.getHealthFacilityDetails())); facilityField.setWidthUndefined(); caseInfoLayout.addComponent(facilityField); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/ConvertToCaseSelectionField.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/ConvertToCaseSelectionField.java index ce2e285e613..d1395172d72 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/ConvertToCaseSelectionField.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/ConvertToCaseSelectionField.java @@ -94,12 +94,12 @@ private void addContactDetailsComponent() { lblLastName.setCaption(I18nProperties.getPrefixCaption(PersonDto.I18N_PREFIX, PersonDto.LAST_NAME)); contactDetailsLayout.addComponent(lblLastName); - final Label lblRegion = new Label(caseDataDto.getResponsibleRegion().toString()); + final Label lblRegion = new Label(caseDataDto.getResponsibleRegion().buildCaption()); lblRegion.setWidthUndefined(); lblRegion.setCaption(I18nProperties.getPrefixCaption(CaseDataDto.I18N_PREFIX, CaseDataDto.RESPONSIBLE_REGION)); contactDetailsLayout.addComponent(lblRegion); - final Label lblDistrict = new Label(caseDataDto.getResponsibleDistrict().toString()); + final Label lblDistrict = new Label(caseDataDto.getResponsibleDistrict().buildCaption()); lblDistrict.setWidthUndefined(); lblDistrict.setCaption(I18nProperties.getPrefixCaption(CaseDataDto.I18N_PREFIX, CaseDataDto.RESPONSIBLE_DISTRICT)); contactDetailsLayout.addComponent(lblDistrict); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/MergeCasesFilterComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/MergeCasesFilterComponent.java index ada569a9d02..aae32e45927 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/MergeCasesFilterComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/MergeCasesFilterComponent.java @@ -144,6 +144,8 @@ private void addSecondRowLayout() { cbRegion = new ComboBox<>(); cbDistrict = new ComboBox<>(); + cbRegion.setItemCaptionGenerator(item -> item.buildCaption()); + cbDistrict.setItemCaptionGenerator(item -> item.buildCaption()); cbRegion.setId(CaseDataDto.REGION); cbRegion.setWidth(200, Unit.PIXELS); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/components/linelisting/LineListingLayout.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/components/linelisting/LineListingLayout.java index bed3da7d6ff..178a0d481f0 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/components/linelisting/LineListingLayout.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/components/linelisting/LineListingLayout.java @@ -94,10 +94,12 @@ public LineListingLayout(Window window) { disease.addValueChangeListener(event -> diseaseDetails.setVisible(Disease.OTHER.equals(disease.getValue()))); region = new ComboBox<>(I18nProperties.getPrefixCaption(CaseDataDto.I18N_PREFIX, CaseDataDto.RESPONSIBLE_REGION)); + region.setItemCaptionGenerator(item -> item.buildCaption()); region.setId("lineListingRegion"); sharedInformationBar.addComponent(region); district = new ComboBox<>(I18nProperties.getPrefixCaption(CaseDataDto.I18N_PREFIX, CaseDataDto.RESPONSIBLE_DISTRICT)); + district.setItemCaptionGenerator(item -> item.buildCaption()); district.setId("lineListingDistrict"); district.addValueChangeListener(e -> setEpidNumberPrefixes()); sharedInformationBar.addComponent(district); @@ -432,6 +434,7 @@ public CaseLineLayout(int lineIndex) { epidNumber.setWidth(160, Unit.PIXELS); binder.forField(epidNumber).bind(CaseLineDto.EPID_NUMBER); community = new ComboBox<>(); + community.setItemCaptionGenerator(item -> item.buildCaption()); community.setId("lineListingCommunity_" + lineIndex); community.addStyleName(CssStyles.SOFT_REQUIRED); community.addValueChangeListener(e -> { @@ -450,6 +453,7 @@ public CaseLineLayout(int lineIndex) { }); binder.forField(community).bind(CaseLineDto.COMMUNITY); facility = new ComboBox<>(); + facility.setItemCaptionGenerator(item -> item.buildCaption()); facility.setId("lineListingFacility_" + lineIndex); facility.setWidth(364, Unit.PIXELS); facility.addValueChangeListener(e -> updateFacilityFields(facility, facilityDetails)); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/importer/CasePickOrImportField.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/importer/CasePickOrImportField.java index 491ded414cb..276f5bc40a9 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/importer/CasePickOrImportField.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/importer/CasePickOrImportField.java @@ -76,20 +76,20 @@ protected void addInfoComponent() { Label responsibleRegionField = new Label(); responsibleRegionField.setCaption(I18nProperties.getPrefixCaption(CaseDataDto.I18N_PREFIX, CaseDataDto.RESPONSIBLE_REGION)); - responsibleRegionField.setValue(newCase.getResponsibleRegion().toString()); + responsibleRegionField.setValue(newCase.getResponsibleRegion().buildCaption()); responsibleRegionField.setWidthUndefined(); caseInfoLayout.addComponent(responsibleRegionField); Label responsibleDistrictField = new Label(); responsibleDistrictField.setCaption(I18nProperties.getPrefixCaption(CaseDataDto.I18N_PREFIX, CaseDataDto.RESPONSIBLE_DISTRICT)); - responsibleDistrictField.setValue(newCase.getResponsibleDistrict().toString()); + responsibleDistrictField.setValue(newCase.getResponsibleDistrict().buildCaption()); responsibleDistrictField.setWidthUndefined(); caseInfoLayout.addComponent(responsibleDistrictField); if (newCase.getRegion() != null) { Label regionField = new Label(); regionField.setCaption(I18nProperties.getPrefixCaption(CaseDataDto.I18N_PREFIX, CaseDataDto.REGION)); - regionField.setValue(newCase.getRegion().toString()); + regionField.setValue(newCase.getRegion().buildCaption()); regionField.setWidthUndefined(); caseInfoLayout.addComponent(regionField); } @@ -97,7 +97,7 @@ protected void addInfoComponent() { if (newCase.getDistrict() != null) { Label districtField = new Label(); districtField.setCaption(I18nProperties.getPrefixCaption(CaseDataDto.I18N_PREFIX, CaseDataDto.DISTRICT)); - districtField.setValue(newCase.getDistrict().toString()); + districtField.setValue(newCase.getDistrict().buildCaption()); districtField.setWidthUndefined(); caseInfoLayout.addComponent(districtField); } @@ -107,7 +107,7 @@ protected void addInfoComponent() { facilityField.setValue( FacilityHelper.buildFacilityString( null, - newCase.getHealthFacility() != null ? newCase.getHealthFacility().toString() : "", + newCase.getHealthFacility() != null ? newCase.getHealthFacility().buildCaption() : "", newCase.getHealthFacilityDetails())); facilityField.setWidthUndefined(); caseInfoLayout.addComponent(facilityField); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/DevModeView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/DevModeView.java index 0facc595804..01a896abdef 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/DevModeView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/DevModeView.java @@ -320,12 +320,14 @@ private VerticalLayout createCaseGeneratorLayout() { List regions = FacadeProvider.getRegionFacade().getAllActiveByServerCountry(); ComboBox regionField = new ComboBox(null, regions); + regionField.setItemCaptionGenerator(item -> item.buildCaption()); regionField.setCaption(I18nProperties.getCaption(Captions.devModeCaseRegion)); caseGeneratorConfigBinder.bind(regionField, CaseGenerationConfig::getRegion, CaseGenerationConfig::setRegion); caseOptionsLayout.addComponent(regionField); ComboBox districtField = new ComboBox(); districtField.setCaption(I18nProperties.getCaption(Captions.devModeCaseDistrict)); + districtField.setItemCaptionGenerator(item -> item.buildCaption()); caseGeneratorConfigBinder.bind(districtField, CaseGenerationConfig::getDistrict, CaseGenerationConfig::setDistrict); caseOptionsLayout.addComponent(districtField); @@ -392,10 +394,12 @@ private VerticalLayout createContactGeneratorLayout() { List regions = FacadeProvider.getRegionFacade().getAllActiveByServerCountry(); ComboBox regionField = new ComboBox(null, regions); regionField.setCaption(I18nProperties.getCaption(Captions.devModeContactRegion)); + regionField.setItemCaptionGenerator(item -> item.buildCaption()); contactGeneratorConfigBinder.bind(regionField, ContactGenerationConfig::getRegion, ContactGenerationConfig::setRegion); contactOptionsFirstLineLayout.addComponent(regionField); ComboBox districtField = new ComboBox(); + districtField.setItemCaptionGenerator(item -> item.buildCaption()); districtField.setCaption(I18nProperties.getCaption(Captions.devModeContactDistrict)); contactGeneratorConfigBinder.bind(districtField, ContactGenerationConfig::getDistrict, ContactGenerationConfig::setDistrict); contactOptionsFirstLineLayout.addComponent(districtField); @@ -485,12 +489,14 @@ private VerticalLayout createEventsGeneratorLayout() { List regions = FacadeProvider.getRegionFacade().getAllActiveAsReference(); ComboBox regionField = new ComboBox(null, regions); + regionField.setItemCaptionGenerator(item -> item.buildCaption()); regionField.setCaption(I18nProperties.getCaption(Captions.devModeEventRegion)); eventGeneratorConfigBinder.bind(regionField, EventGenerationConfig::getRegion, EventGenerationConfig::setRegion); eventOptionsFirstLineLayout.addComponent(regionField); ComboBox districtField = new ComboBox(); districtField.setCaption(I18nProperties.getCaption(Captions.devModeEventDistrict)); + districtField.setItemCaptionGenerator(item -> item.buildCaption()); eventGeneratorConfigBinder.bind(districtField, EventGenerationConfig::getDistrict, EventGenerationConfig::setDistrict); eventOptionsFirstLineLayout.addComponent(districtField); @@ -599,11 +605,13 @@ private VerticalLayout createSamplesGeneratorLayout() { List regions = FacadeProvider.getRegionFacade().getAllActiveByServerCountry(); ComboBox regionField = new ComboBox<>(null, regions); regionField.setCaption(I18nProperties.getCaption(Captions.devModeSampleRegion)); + regionField.setItemCaptionGenerator(item -> item.buildCaption()); sampleGeneratorConfigBinder.bind(regionField, SampleGenerationConfig::getRegion, SampleGenerationConfig::setRegion); sampleOptionsFirstLineLayout.addComponent(regionField); ComboBox districtField = new ComboBox<>(); districtField.setCaption(I18nProperties.getCaption(Captions.devModeSampleDistrict)); + districtField.setItemCaptionGenerator(item -> item.buildCaption()); sampleGeneratorConfigBinder.bind(districtField, SampleGenerationConfig::getDistrict, SampleGenerationConfig::setDistrict); sampleOptionsFirstLineLayout.addComponent(districtField); @@ -631,6 +639,7 @@ private VerticalLayout createSamplesGeneratorLayout() { sampleOptionsSecondLineLayout.addComponent(sampleMaterial); ComboBox laboratory = new ComboBox(null, FacadeProvider.getFacilityFacade().getAllActiveLaboratories(true)); + laboratory.setItemCaptionGenerator(item -> item.buildCaption()); laboratory.setCaption(I18nProperties.getCaption(Captions.devModeSampleLaboratory)); sampleGeneratorConfigBinder.bind(laboratory, SampleGenerationConfig::getLaboratory, SampleGenerationConfig::setLaboratory); laboratory.setRequiredIndicatorVisible(true); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/components/CountryCombo.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/components/CountryCombo.java index 4f8ee2d8235..96909500203 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/components/CountryCombo.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/components/CountryCombo.java @@ -18,14 +18,14 @@ import java.util.function.BiConsumer; import com.vaadin.v7.shared.ui.combobox.FilteringMode; -import com.vaadin.v7.ui.ComboBox; import de.symeda.sormas.api.FacadeProvider; import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.infrastructure.country.CountryReferenceDto; import de.symeda.sormas.api.infrastructure.region.RegionDto; +import de.symeda.sormas.ui.utils.ComboBoxWithPlaceholder; -public class CountryCombo extends ComboBox { +public class CountryCombo extends ComboBoxWithPlaceholder { public CountryCombo(BiConsumer changeHandler) { setId(RegionDto.COUNTRY); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/linelisting/LineListingConfigurationView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/linelisting/LineListingConfigurationView.java index 6e00e73d6e0..a7ee3cbc22d 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/linelisting/LineListingConfigurationView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/linelisting/LineListingConfigurationView.java @@ -65,7 +65,7 @@ private void buildView(Disease enteredDisease) { } if (region != null) { - getViewSubTitleLabel().setValue(region.toString()); + getViewSubTitleLabel().setValue(region.buildCaption()); } Label infoTextLabel; @@ -215,7 +215,7 @@ private void openEditWindow(Disease disease) { LineListingConfigurationEditLayout editLayout = new LineListingConfigurationEditLayout( FacadeProvider.getFeatureConfigurationFacade().getFeatureConfigurations(criteria, true), disease, - region != null ? region.toString() : null); + region != null ? region.buildCaption() : null); editLayout.setSaveCallback(() -> { Notification.show(null, I18nProperties.getString(Strings.messageLineListingSaved), Type.TRAY_NOTIFICATION); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/linelisting/LineListingRegionsLayout.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/linelisting/LineListingRegionsLayout.java index 6947f2a9fe5..7985cb4c438 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/linelisting/LineListingRegionsLayout.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/linelisting/LineListingRegionsLayout.java @@ -32,7 +32,7 @@ public LineListingRegionsLayout(List configuration this.regions = new TreeMap<>((r1, r2) -> regionNames.get(r1).compareTo(regionNames.get(r2))); for (RegionReferenceDto region : FacadeProvider.getRegionFacade().getAllActiveByServerCountry()) { - regionNames.put(region.getUuid(), region.toString()); + regionNames.put(region.getUuid(), region.buildCaption()); regions.put(region.getUuid(), new ArrayList<>()); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/outbreak/OutbreakController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/outbreak/OutbreakController.java index 84a2d0fda60..f5482984093 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/outbreak/OutbreakController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/outbreak/OutbreakController.java @@ -42,7 +42,7 @@ public void openOutbreakConfigurationWindow(Disease disease, OutbreakRegionConfi Window popupWindow = VaadinUiUtil.showModalPopupWindow( configurationComponent, disease.toShortString() + " " + I18nProperties.getString(Strings.headingOutbreakIn) + " " - + diseaseOutbreakInformation.getRegion().toString()); + + diseaseOutbreakInformation.getRegion().buildCaption()); configurationComponent.addCommitListener(new CommitListener() { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/outbreak/OutbreakOverviewGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/outbreak/OutbreakOverviewGrid.java index eee25fb7752..d0d579980b5 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/outbreak/OutbreakOverviewGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/outbreak/OutbreakOverviewGrid.java @@ -45,6 +45,7 @@ import de.symeda.sormas.ui.UserProvider; import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.LayoutUtil; +import de.symeda.sormas.ui.utils.V7CaptionConverter; @SuppressWarnings("serial") public class OutbreakOverviewGrid extends Grid implements ItemClickListener { @@ -60,7 +61,8 @@ public OutbreakOverviewGrid() { user = UserProvider.getCurrent().getUser(); - addColumn(REGION, RegionReferenceDto.class).setMaximumWidth(200); + Column column = addColumn(REGION, RegionReferenceDto.class).setMaximumWidth(200); + column.setRenderer(new HtmlRenderer(), new V7CaptionConverter()); getColumn(REGION).setHeaderCaption(I18nProperties.getCaption(Captions.Region)); for (Disease disease : FacadeProvider.getDiseaseConfigurationFacade().getAllDiseases(true, true, true)) { @@ -158,7 +160,7 @@ private String getCellDescription(CellReference cell) { int index = 0; for (DistrictReferenceDto affectedDistrict : affectedDistricts) { - affectedDistrictsStringBuilder.append(affectedDistrict.toString()); + affectedDistrictsStringBuilder.append(affectedDistrict.buildCaption()); if (index < affectedDistricts.size() - 1) { affectedDistrictsStringBuilder.append(", "); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/outbreak/OutbreakRegionConfigurationForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/outbreak/OutbreakRegionConfigurationForm.java index 563d810682e..74488404909 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/outbreak/OutbreakRegionConfigurationForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/outbreak/OutbreakRegionConfigurationForm.java @@ -189,7 +189,7 @@ private OptionGroup createOutbreakToggle(DistrictReferenceDto district) { ValoTheme.OPTIONGROUP_HORIZONTAL, CssStyles.OPTIONGROUP_HORIZONTAL_SWITCH_CRITICAL, CssStyles.OPTIONGROUP_CAPTION_INLINE); - outbreakToggle.setCaption(district.toString()); + outbreakToggle.setCaption(district.buildCaption()); outbreakToggle.addItem(OUTBREAK); outbreakToggle.addItem(NORMAL); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/MergeContactsFilterComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/MergeContactsFilterComponent.java index 028e7bc229f..1f0f17a1110 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/MergeContactsFilterComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/MergeContactsFilterComponent.java @@ -148,6 +148,8 @@ private void addSecondRowLayout() { cbRegion = new ComboBox<>(); cbDistrict = new ComboBox<>(); + cbRegion.setItemCaptionGenerator(item -> item.buildCaption()); + cbDistrict.setItemCaptionGenerator(item -> item.buildCaption()); cbRegion.setId(ContactDto.REGION); cbRegion.setWidth(200, Unit.PIXELS); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/components/linelisting/sharedinfo/SharedInfoField.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/components/linelisting/sharedinfo/SharedInfoField.java index d2e0561fffe..d554f6fd854 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/components/linelisting/sharedinfo/SharedInfoField.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/components/linelisting/sharedinfo/SharedInfoField.java @@ -45,6 +45,9 @@ public SharedInfoField(CaseReferenceDto caseReferenceDto, Disease initialDisease disease = new ComboBox<>(I18nProperties.getCaption(Captions.lineListingDiseaseOfSourceCase)); region = new ComboBox<>(I18nProperties.getCaption(Captions.Region)); district = new ComboBox<>(I18nProperties.getCaption(Captions.District)); + region.setItemCaptionGenerator(item -> item.buildCaption()); + district.setItemCaptionGenerator(item -> item.buildCaption()); + this.initialDiseaseValue = initialDiseaseValue; } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/docgeneration/QuarantineOrderLayout.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/docgeneration/QuarantineOrderLayout.java index 97b93e2fe11..c447770dae8 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/docgeneration/QuarantineOrderLayout.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/docgeneration/QuarantineOrderLayout.java @@ -103,8 +103,10 @@ protected void createSampleSelector(SampleCriteria sampleCriteria) { pathogenTestSelector.setWidth(100F, Unit.PERCENTAGE); pathogenTestSelector.setItemCaptionGenerator(e -> e.buildCaption()); pathogenTestSelector.setEnabled(false); + pathogenTestSelector.setItemCaptionGenerator(item -> item.buildCaption()); sampleSelector = new ComboBox<>(I18nProperties.getCaption(Captions.Sample)); + sampleSelector.setItemCaptionGenerator(item -> item.buildCaption()); sampleSelector.setWidth(100F, Unit.PERCENTAGE); sampleSelector.setItemCaptionGenerator(e -> e.getCaption()); sampleSelector.setItems(samples); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/exposure/ExposuresField.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/exposure/ExposuresField.java index a9016833277..89faf90f54d 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/exposure/ExposuresField.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/exposure/ExposuresField.java @@ -185,7 +185,7 @@ private void addGeneratedColumns(Table table) { if (StringUtils.isNotEmpty(exposure.getLocation().getFacilityDetails())) { typeOfPlaceString += " - " + exposure.getLocation().getFacilityDetails(); } else if (exposure.getLocation().getFacility() != null) { - typeOfPlaceString += " - " + exposure.getLocation().getFacility().toString(); + typeOfPlaceString += " - " + exposure.getLocation().getFacility().buildCaption(); } } else if (exposure.getTypeOfPlace() == TypeOfPlace.MEANS_OF_TRANSPORT) { typeOfPlaceString = exposure.getMeansOfTransport() == null @@ -227,7 +227,7 @@ private void addGeneratedColumns(Table table) { table.addGeneratedColumn(COLUMN_SOURCE_CASE_NAME, (Table.ColumnGenerator) (source, itemId, columnId) -> { ExposureDto exposure = (ExposureDto) itemId; return !isPseudonymized - ? DataHelper.toStringNullable(exposure.getContactToCase() != null ? exposure.getContactToCase().getCaseName() : "") + ? DataHelper.toStringNullable(exposure.getContactToCase() != null ? exposure.getContactToCase().getCaseName().buildCaption() : "") : I18nProperties.getCaption(Captions.inaccessibleValue); }); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/hospitalization/HospitalizationForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/hospitalization/HospitalizationForm.java index 178c0888f2f..4b8bd2ab756 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/hospitalization/HospitalizationForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/hospitalization/HospitalizationForm.java @@ -302,7 +302,7 @@ private String getHospitalName(FacilityReferenceDto healthFacility, CaseDataDto return null; } StringBuilder hospitalName = new StringBuilder(); - hospitalName.append(healthFacility.toString()); + hospitalName.append(healthFacility.buildCaption()); if (caze.getHealthFacilityDetails() != null && caze.getHealthFacilityDetails().trim().length() > 0) { hospitalName.append(String.format(HOSPITAL_NAME_DETAIL, caze.getHealthFacilityDetails())); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonSelectionField.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonSelectionField.java index cab92e40e52..4d1d4a644aa 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonSelectionField.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonSelectionField.java @@ -137,14 +137,14 @@ private void addPersonDetailsComponent() { addLabelIfVisible( personDetailsLayout2, - referencePerson.getAddress().getDistrict() != null ? referencePerson.getAddress().getDistrict().toString() : "", + referencePerson.getAddress().getDistrict() != null ? referencePerson.getAddress().getDistrict().buildCaption() : "", LocationDto.I18N_PREFIX, LocationDto.DISTRICT, LocationDto.class); addLabelIfVisible( personDetailsLayout2, - referencePerson.getAddress().getCommunity() != null ? referencePerson.getAddress().getCommunity().toString() : "", + referencePerson.getAddress().getCommunity() != null ? referencePerson.getAddress().getCommunity().buildCaption() : "", LocationDto.I18N_PREFIX, LocationDto.COMMUNITY, LocationDto.class); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/reports/WeeklyReportOfficersGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/reports/WeeklyReportOfficersGrid.java index eef86b01df9..860746da4f4 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/reports/WeeklyReportOfficersGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/reports/WeeklyReportOfficersGrid.java @@ -190,7 +190,7 @@ public void itemClick(ItemClickEvent event) { grid.setHeightUndefined(); layout.addComponent(grid); window.setCaption( - String.format(I18nProperties.getCaption(Captions.weeklyReportsInDistrict), summaryDto.getDistrict().toString()) + " - " + String.format(I18nProperties.getCaption(Captions.weeklyReportsInDistrict), summaryDto.getDistrict().buildCaption()) + " - " + I18nProperties.getString(Strings.epiWeek) + " " + week + "/" + year); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/reports/WeeklyReportRegionsGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/reports/WeeklyReportRegionsGrid.java index 6297770de26..3002e40ea2b 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/reports/WeeklyReportRegionsGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/reports/WeeklyReportRegionsGrid.java @@ -38,6 +38,7 @@ import de.symeda.sormas.api.utils.EpiWeek; import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.PercentageRenderer; +import de.symeda.sormas.ui.utils.V7CaptionConverter; import de.symeda.sormas.ui.utils.VaadinUiUtil; @SuppressWarnings("serial") @@ -104,6 +105,9 @@ public WeeklyReportRegionsGrid() { column.setHeaderCaption(""); column.setSortable(false); } else { + if (column.getPropertyId().equals(WeeklyReportRegionSummaryDto.REGION)) { + column.setConverter(new V7CaptionConverter()); + } column.setHeaderCaption( I18nProperties .getPrefixCaption(WeeklyReportRegionSummaryDto.I18N_PREFIX, column.getPropertyId().toString(), column.getHeaderCaption())); @@ -179,7 +183,7 @@ public void itemClick(ItemClickEvent event) { grid.setHeightUndefined(); layout.addComponent(grid); window.setCaption( - String.format(I18nProperties.getCaption(Captions.weeklyReportsInDistrict), summaryDto.getRegion().toString()) + " - " + String.format(I18nProperties.getCaption(Captions.weeklyReportsInDistrict), summaryDto.getRegion().buildCaption()) + " - " + I18nProperties.getString(Strings.epiWeek) + " " + week + "/" + year); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/reports/aggregate/AggregateReportsEditLayout.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/reports/aggregate/AggregateReportsEditLayout.java index a33a8ae3a5c..e9c0956572b 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/reports/aggregate/AggregateReportsEditLayout.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/reports/aggregate/AggregateReportsEditLayout.java @@ -118,6 +118,7 @@ public AggregateReportsEditLayout(Window window, boolean edit, AggregateReportDt comboBoxRegion = new ComboBox<>(); comboBoxRegion.setWidth(250, Unit.PIXELS); + comboBoxRegion.setItemCaptionGenerator(item -> item.buildCaption()); comboBoxRegion.setCaption(I18nProperties.getPrefixCaption(AggregateReportDto.I18N_PREFIX, AggregateReportDto.REGION)); comboBoxRegion.setItems(FacadeProvider.getRegionFacade().getAllActiveByServerCountry()); comboBoxRegion.setRequiredIndicatorVisible(true); @@ -136,6 +137,7 @@ public AggregateReportsEditLayout(Window window, boolean edit, AggregateReportDt }); comboBoxDistrict = new ComboBox<>(); + comboBoxDistrict.setItemCaptionGenerator(item -> item.buildCaption()); comboBoxDistrict.setWidth(250, Unit.PIXELS); comboBoxDistrict.setCaption(I18nProperties.getPrefixCaption(AggregateReportDto.I18N_PREFIX, AggregateReportDto.DISTRICT)); comboBoxDistrict.setRequiredIndicatorVisible(true); @@ -169,6 +171,7 @@ public AggregateReportsEditLayout(Window window, boolean edit, AggregateReportDt addComponent(new HorizontalLayout(comboBoxRegion, comboBoxDistrict)); comboBoxFacility = new ComboBox<>(); + comboBoxFacility.setItemCaptionGenerator(item -> item.buildCaption()); comboBoxFacility.setWidth(250, Unit.PIXELS); comboBoxFacility.setCaption(I18nProperties.getPrefixCaption(AggregateReportDto.I18N_PREFIX, AggregateReportDto.HEALTH_FACILITY)); comboBoxFacility.setEnabled(false); @@ -180,6 +183,7 @@ public AggregateReportsEditLayout(Window window, boolean edit, AggregateReportDt }); comboBoxPoe = new ComboBox<>(); + comboBoxPoe.setItemCaptionGenerator(item -> item.buildCaption()); comboBoxPoe.setWidth(250, Unit.PIXELS); comboBoxPoe.setCaption(I18nProperties.getPrefixCaption(AggregateReportDto.I18N_PREFIX, AggregateReportDto.POINT_OF_ENTRY)); comboBoxPoe.setEnabled(false); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/AbstractSampleForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/AbstractSampleForm.java index 875ea5e988b..69c3dae8f53 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/AbstractSampleForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/AbstractSampleForm.java @@ -240,7 +240,7 @@ protected void defaultValueChangeListener() { .append(" ") .append(DateFormatHelper.formatLocalDateTime(getValue().getReportDateTime())); if (reportingUser != null) { - reportInfoText.append(" ").append(I18nProperties.getString(Strings.by)).append(" ").append(reportingUser.toString()); + reportInfoText.append(" ").append(I18nProperties.getString(Strings.by)).append(" ").append(reportingUser.buildCaption()); } Label reportInfoLabel = new Label(reportInfoText.toString()); reportInfoLabel.setEnabled(false); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleController.java index b7f1095780a..e1aadd385a1 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleController.java @@ -459,7 +459,7 @@ public void buttonClick(ClickEvent event) { String referOrLinkToOtherLabButtonCaption = referredDtoLab == null ? I18nProperties.getCaption(Captions.sampleReferredToInternal) + " (" + DateFormatHelper.formatLocalDateTime(referredDto.getSampleDateTime()) + ")" - : I18nProperties.getCaption(Captions.sampleReferredTo) + " " + referredDtoLab.toString(); + : I18nProperties.getCaption(Captions.sampleReferredTo) + " " + referredDtoLab.buildCaption(); referOrLinkToOtherLabButton = ButtonHelper.createButton("referOrLinkToOtherLab", referOrLinkToOtherLabButtonCaption, new ClickListener() { @@ -494,7 +494,7 @@ public void addReferredFromButton(CommitDiscardWrapperComponent String referredButtonCaption = referredFromLab == null ? I18nProperties.getCaption(Captions.sampleReferredFromInternal) + " (" + DateFormatHelper.formatLocalDateTime(referredFrom.getSampleDateTime()) + ")" - : I18nProperties.getCaption(Captions.sampleReferredFrom) + " " + referredFromLab.toString(); + : I18nProperties.getCaption(Captions.sampleReferredFrom) + " " + referredFromLab.buildCaption(); Button referredButton = ButtonHelper .createButton("referredFrom", referredButtonCaption, event -> navigation.accept(referredFrom), ValoTheme.BUTTON_LINK, VSPACE_NONE); editForm.getWrappedComponent().addReferredFromButton(referredButton); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/CasePreviewGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/CasePreviewGrid.java index c6e065071ba..6bbc806acb0 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/CasePreviewGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/CasePreviewGrid.java @@ -38,6 +38,7 @@ import de.symeda.sormas.api.symptoms.SymptomsDto; import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.ui.ControllerProvider; +import de.symeda.sormas.ui.utils.CaptionRenderer; import de.symeda.sormas.ui.utils.UuidRenderer; public class CasePreviewGrid extends BasePreviewGrid { @@ -121,6 +122,12 @@ protected void buildGrid() { ((Column) getColumn(SormasToSormasCasePreview.ONSET_DATE)) .setRenderer(new DateRenderer(DateHelper.getLocalDateTimeFormat(userLanguage))); + getColumn(SormasToSormasCasePreview.REGION).setRenderer(new CaptionRenderer()); + getColumn(SormasToSormasCasePreview.DISTRICT).setRenderer(new CaptionRenderer()); + getColumn(SormasToSormasCasePreview.COMMUNITY).setRenderer(new CaptionRenderer()); + getColumn(SormasToSormasCasePreview.HEALTH_FACILITY).setRenderer(new CaptionRenderer()); + getColumn(SormasToSormasCasePreview.POINT_OF_ENTRY).setRenderer(new CaptionRenderer()); + for (Column column : getColumns()) { column.setCaption( I18nProperties.findPrefixCaption( diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/ContactsPreviewGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/ContactsPreviewGrid.java index 4fb4ee0570f..69b41b990aa 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/ContactsPreviewGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/ContactsPreviewGrid.java @@ -29,10 +29,12 @@ import de.symeda.sormas.api.Language; import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.i18n.I18nProperties; +import de.symeda.sormas.api.sormastosormas.share.incoming.SormasToSormasCasePreview; import de.symeda.sormas.api.sormastosormas.share.incoming.SormasToSormasContactPreview; import de.symeda.sormas.api.sormastosormas.share.incoming.SormasToSormasPersonPreview; import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.ui.ControllerProvider; +import de.symeda.sormas.ui.utils.CaptionRenderer; import de.symeda.sormas.ui.utils.UuidRenderer; public class ContactsPreviewGrid extends BasePreviewGrid { @@ -89,6 +91,10 @@ protected void buildGrid() { ((Column) getColumn(SormasToSormasContactPreview.LAST_CONTACT_DATE)) .setRenderer(new DateRenderer(DateHelper.getLocalDateTimeFormat(userLanguage))); + getColumn(SormasToSormasCasePreview.REGION).setRenderer(new CaptionRenderer()); + getColumn(SormasToSormasCasePreview.DISTRICT).setRenderer(new CaptionRenderer()); + getColumn(SormasToSormasCasePreview.COMMUNITY).setRenderer(new CaptionRenderer()); + for (Column column : getColumns()) { column.setCaption( I18nProperties.findPrefixCaption(column.getId(), SormasToSormasContactPreview.I18N_PREFIX, SormasToSormasPersonPreview.I18N_PREFIX)); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserGrid.java index ec3636f625e..c8749ba0063 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserGrid.java @@ -27,7 +27,6 @@ import de.symeda.sormas.api.FacadeProvider; import de.symeda.sormas.api.i18n.I18nProperties; -import de.symeda.sormas.api.location.LocationDto; import de.symeda.sormas.api.user.UserCriteria; import de.symeda.sormas.api.user.UserDto; import de.symeda.sormas.api.user.UserRight; @@ -36,7 +35,6 @@ import de.symeda.sormas.ui.ControllerProvider; import de.symeda.sormas.ui.UserProvider; import de.symeda.sormas.ui.ViewModelProviders; -import de.symeda.sormas.ui.utils.CaptionRenderer; import de.symeda.sormas.ui.utils.FilteredGrid; import de.symeda.sormas.ui.utils.UuidRenderer; import de.symeda.sormas.ui.utils.ViewConfiguration; @@ -79,7 +77,6 @@ public UserGrid() { userRolesColumn.setRenderer(new UserRolesRenderer()); userRolesColumn.setSortable(false); ((Column) getColumn(UserDto.ACTIVE)).setRenderer(value -> String.valueOf(value), new ActiveRenderer()); - ((Column) getColumn(UserDto.ADDRESS)).setRenderer(new CaptionRenderer()); for (Column column : getColumns()) { column.setCaption(I18nProperties.getPrefixCaption(UserDto.I18N_PREFIX, column.getId().toString(), column.getCaption())); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CaptionRenderer.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CaptionRenderer.java index e36032a8cd4..d6dc93ad28c 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CaptionRenderer.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CaptionRenderer.java @@ -19,7 +19,7 @@ import com.vaadin.ui.renderers.TextRenderer; -import de.symeda.sormas.api.EntityDto; +import de.symeda.sormas.api.utils.HasCaption; import elemental.json.JsonValue; @SuppressWarnings("serial") @@ -32,10 +32,10 @@ public JsonValue encode(Object value) { return null; } - if (!EntityDto.class.isAssignableFrom(value.getClass())) { - return null; + if (!HasCaption.class.isAssignableFrom(value.getClass())) { + return super.encode(value.toString()); } - return super.encode(((EntityDto) value).buildCaption()); + return super.encode(((HasCaption) value).buildCaption()); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/ComboBoxHelper.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/ComboBoxHelper.java index 245288d6905..7c2886bb5e7 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/ComboBoxHelper.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/ComboBoxHelper.java @@ -1,15 +1,14 @@ package de.symeda.sormas.ui.utils; import com.vaadin.v7.shared.ui.combobox.FilteringMode; -import com.vaadin.v7.ui.ComboBox; public class ComboBoxHelper { /** * Create a default V7 combobox which uses FilteringMode.CONTAINS */ - public static ComboBox createComboBoxV7() { - ComboBox cb = new ComboBox(); + public static ComboBoxWithPlaceholder createComboBoxV7() { + ComboBoxWithPlaceholder cb = new ComboBoxWithPlaceholder(); cb.setFilteringMode(FilteringMode.CONTAINS); return cb; } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/ComboBoxWithPlaceholder.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/ComboBoxWithPlaceholder.java index d4c80540011..54641a0b769 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/ComboBoxWithPlaceholder.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/ComboBoxWithPlaceholder.java @@ -15,6 +15,7 @@ package de.symeda.sormas.ui.utils; +import java.util.Collection; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; @@ -23,18 +24,44 @@ import com.vaadin.v7.ui.ComboBox; import de.symeda.sormas.api.ReferenceDto; +import de.symeda.sormas.api.utils.HasCaption; public class ComboBoxWithPlaceholder extends ComboBox { private static final long serialVersionUID = 27751677500982303L; PlaceholderReferenceDto placeholder = null; + private boolean ignoreDirtyMarkingOnGetOfHasCaption = false; public ComboBoxWithPlaceholder() { super(); this.setFilteringMode(FilteringMode.CONTAINS); } + @Override + public String getItemCaption(Object itemId) { + if (itemId instanceof HasCaption) { + ignoreDirtyMarkingOnGetOfHasCaption = true; + this.setItemCaption(itemId, ((HasCaption) itemId).buildCaption()); + ignoreDirtyMarkingOnGetOfHasCaption = false; + } + return super.getItemCaption(itemId); + } + + public void markAsDirty() { + if (!ignoreDirtyMarkingOnGetOfHasCaption) { + super.markAsDirty(); + } + } + + @Override + public void addItems(Collection itemIds) throws UnsupportedOperationException { + super.addItems(itemIds); + for (Object item : itemIds) { + this.setItemCaption(item, item instanceof HasCaption ? ((HasCaption) item).buildCaption() : item.toString()); + } + } + @Override public boolean removeAllItems() throws UnsupportedOperationException { AtomicBoolean retVal = new AtomicBoolean(false); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FilteredGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FilteredGrid.java index 67d5518da54..83958122d34 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FilteredGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FilteredGrid.java @@ -1,6 +1,7 @@ package de.symeda.sormas.ui.utils; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.function.Consumer; @@ -25,7 +26,9 @@ 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.UserDto; import de.symeda.sormas.api.user.UserRight; +import de.symeda.sormas.api.utils.HasCaption; import de.symeda.sormas.api.utils.SortProperty; import de.symeda.sormas.api.utils.criteria.BaseCriteria; import de.symeda.sormas.api.utils.pseudonymization.PseudonymizableIndexDto; @@ -212,6 +215,12 @@ public void setDataProvider(FetchItemsCallback fetchItems, SerializableSuppli public void setColumns(String... columnIds) { super.setColumns(columnIds); getColumns().forEach(tColumn -> tColumn.setMaximumWidth(300)); + + Arrays.asList(columnIds).forEach(columnId -> { + if (!columnId.equals(ACTION_BTN_ID)) { + ((Column) getColumn(columnId)).setRenderer(new CaptionRenderer()); + } + }); } /** diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/OptionGroupWithCaption.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/OptionGroupWithCaption.java new file mode 100644 index 00000000000..4bd71b0bbe2 --- /dev/null +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/OptionGroupWithCaption.java @@ -0,0 +1,34 @@ +/* + * SORMAS® - Surveillance Outbreak Response Management & Analysis System + * Copyright © 2016-2022 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package de.symeda.sormas.ui.utils; + +import java.util.Collection; + +import com.vaadin.v7.ui.OptionGroup; + +import de.symeda.sormas.api.utils.HasCaption; + +public class OptionGroupWithCaption extends OptionGroup { + + @Override + public void addItems(Collection itemIds) throws UnsupportedOperationException { + super.addItems(itemIds); + for (Object item : itemIds) { + this.setItemCaption(item, item instanceof HasCaption ? ((HasCaption) item).buildCaption() : item.toString()); + } + } +} diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/SormasFieldGroupFieldFactory.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/SormasFieldGroupFieldFactory.java index 1d3af9221b4..19bb5ed1e92 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/SormasFieldGroupFieldFactory.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/SormasFieldGroupFieldFactory.java @@ -112,6 +112,11 @@ public T createField(Class type, Class fieldType) { combo.setImmediate(true); return (T) combo; + } else if (OptionGroup.class.isAssignableFrom(fieldType) || OptionGroupWithCaption.class.isAssignableFrom(fieldType)) { + OptionGroupWithCaption optionGroupWithCaption = new OptionGroupWithCaption(); + optionGroupWithCaption.setImmediate(true); + + return (T) optionGroupWithCaption; } else if (AbstractSelect.class.isAssignableFrom(fieldType)) { AbstractSelect field = createCompatibleSelect((Class) fieldType); field.setNullSelectionAllowed(true); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/V7CaptionConverter.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/V7CaptionConverter.java new file mode 100644 index 00000000000..b63bc938d54 --- /dev/null +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/V7CaptionConverter.java @@ -0,0 +1,45 @@ +/* + * SORMAS® - Surveillance Outbreak Response Management & Analysis System + * Copyright © 2016-2022 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.symeda.sormas.ui.utils; + +import java.util.Locale; + +import com.vaadin.v7.data.util.converter.Converter; + +import de.symeda.sormas.api.utils.HasCaption; + +public class V7CaptionConverter implements Converter { + + @Override + public HasCaption convertToModel(String s, Class aClass, Locale locale) throws ConversionException { + throw new RuntimeException("Not implemented"); + } + + @Override + public String convertToPresentation(HasCaption hasCaption, Class aClass, Locale locale) throws ConversionException { + return hasCaption.buildCaption(); + } + + @Override + public Class getModelType() { + return HasCaption.class; + } + + @Override + public Class getPresentationType() { + return String.class; + } +} From 5f765d70e81119396338993dac81ec7821da525b Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Wed, 11 Jan 2023 13:42:53 +0100 Subject: [PATCH 104/166] fix --- .../steps/web/application/events/EditEventSteps.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java index 896486a1ea8..93f1e1e2c5e 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java @@ -1929,8 +1929,8 @@ public EditEventSteps( "Default option is not 'All event participants'"); Assert.assertTrue( webDriverHelpers.checkIfElementExistsInCombobox( - EVENT_PARTICIPANT_STATUS, "All event participants"), - "There is no 'All event participants' option in drop list."); + EVENT_PARTICIPANT_STATUS, "Active and archived event participants"), + "There is no 'Active and archived event participants' option in drop list."); Assert.assertTrue( webDriverHelpers.checkIfElementExistsInCombobox( EVENT_PARTICIPANT_STATUS, "Active event participants"), @@ -1939,6 +1939,10 @@ public EditEventSteps( webDriverHelpers.checkIfElementExistsInCombobox( EVENT_PARTICIPANT_STATUS, "Archived event participants"), "There is no 'Archived event participants' option in drop list."); + Assert.assertTrue( + webDriverHelpers.checkIfElementExistsInCombobox( + EVENT_PARTICIPANT_STATUS, "Deleted event participants"), + "There is no 'Deleted event participants' option in drop list."); }); And( From 73aadaf6137bd58286022cf025b87fe00e1df786 Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Wed, 11 Jan 2023 13:54:52 +0100 Subject: [PATCH 105/166] fix --- .../steps/web/application/events/EditEventSteps.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java index 93f1e1e2c5e..67f42b91ce9 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/events/EditEventSteps.java @@ -1950,12 +1950,12 @@ public EditEventSteps( () -> { Assert.assertEquals( webDriverHelpers.getValueFromCombobox(EVENT_PARTICIPANT_STATUS), - "All event participants", - "Default option is not 'All event participants'"); + "Active and archived event participants", + "Default option is not 'Active and archived event participants'"); Assert.assertTrue( webDriverHelpers.checkIfElementExistsInCombobox( - EVENT_PARTICIPANT_STATUS, "All event participants"), - "There is no 'All event participants' option in drop list."); + EVENT_PARTICIPANT_STATUS, "Active and archived event participants"), + "There is no 'Active and archived event participants' option in drop list."); Assert.assertTrue( webDriverHelpers.checkIfElementExistsInCombobox( EVENT_PARTICIPANT_STATUS, "Active event participants"), @@ -1964,6 +1964,10 @@ public EditEventSteps( webDriverHelpers.checkIfElementExistsInCombobox( EVENT_PARTICIPANT_STATUS, "Archived event participants"), "There is no 'Archived event participants' option in drop list."); + Assert.assertTrue( + webDriverHelpers.checkIfElementExistsInCombobox( + EVENT_PARTICIPANT_STATUS, "Deleted event participants"), + "There is no 'Deleted event participants' option in drop list."); }); When( From 832a9d1166ca77243210cf7e687c5f1c4cfc0f0f Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Wed, 11 Jan 2023 14:15:55 +0100 Subject: [PATCH 106/166] fix --- .../e2etests/steps/web/application/cases/EditCaseSteps.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/cases/EditCaseSteps.java index 887039fadac..de99f222552 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 @@ -424,7 +424,7 @@ public EditCaseSteps( String sampleDate = CreateNewSampleSteps.sample .getDateOfCollection() - .format(DateTimeFormatter.ofPattern("M/dd/yyyy")); + .format(DateTimeFormatter.ofPattern("M/d/yyyy")); Assert.assertTrue( sampleFieldValue.startsWith(sampleDate), "Sample field date doesn't start with " + sampleDate); From deb1d9e175fd8c1aa8933b74da65d09d18623685 Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Wed, 11 Jan 2023 14:33:40 +0100 Subject: [PATCH 107/166] fix --- .../src/test/resources/features/sanity/web/Case.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 2b365028eb1..d687a093d24 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 @@ -1799,7 +1799,7 @@ Feature: Case end to end tests And I back to the cases list from edit case And I apply "Archived cases" to combobox on Case Directory Page And I check that number of displayed cases results is 1 - And I apply "All cases" to combobox on Case Directory Page + And I apply "All active and archived cases" to combobox on Case Directory Page And I check that number of displayed cases results is 1 @tmsLink=SORDEV-12441 @env_de From 4e93f99de925fe8df79d1bd256f9d686926459fb Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Wed, 11 Jan 2023 17:50:00 +0100 Subject: [PATCH 108/166] fixes --- .../application/users/UserRolesPage.java | 1 + .../web/application/users/UserRolesSteps.java | 22 +++++++++++++++++++ .../features/sanity/web/User.feature | 3 +++ 3 files changed, 26 insertions(+) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/users/UserRolesPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/users/UserRolesPage.java index c37756bcc51..f49e9f00ce1 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/users/UserRolesPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/users/UserRolesPage.java @@ -32,6 +32,7 @@ public class UserRolesPage { public static By ARCHIVE_CASES_CHECKBOX = By.xpath("//label[text()='Archive cases']"); public static By ARCHIVE_CONTACTS_CHECKBOX = By.xpath("//label[text()='Archive contacts']"); public static By SAVE_BUTTON = By.cssSelector("#commit"); + public static By DISCARD_BUTTON = By.cssSelector("#discard"); public static By USER_ROLE_LIST = By.cssSelector("#tab-user-userroles"); public static By getUserRoleCaptionByText(String caption) { diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/users/UserRolesSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/users/UserRolesSteps.java index ce88b5ff104..e748dd0e396 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/users/UserRolesSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/users/UserRolesSteps.java @@ -26,6 +26,7 @@ import static org.sormas.e2etests.pages.application.users.UserRolesPage.CAPTION_INPUT; import static org.sormas.e2etests.pages.application.users.UserRolesPage.DELETE_CONFIRMATION_BUTTON; import static org.sormas.e2etests.pages.application.users.UserRolesPage.DELETE_USER_ROLE_BUTTON; +import static org.sormas.e2etests.pages.application.users.UserRolesPage.DISCARD_BUTTON; import static org.sormas.e2etests.pages.application.users.UserRolesPage.ENABLED_DISABLED_SEARCH_COMBOBOX; import static org.sormas.e2etests.pages.application.users.UserRolesPage.EXPORT_USER_ROLES_BUTTON; import static org.sormas.e2etests.pages.application.users.UserRolesPage.NEW_USER_ROLE_BUTTON; @@ -43,6 +44,7 @@ import cucumber.api.java8.En; import java.time.LocalDate; +import java.util.concurrent.TimeUnit; import javax.inject.Inject; import org.sormas.e2etests.helpers.WebDriverHelpers; import org.sormas.e2etests.helpers.files.FilesHelper; @@ -269,5 +271,25 @@ public UserRolesSteps(WebDriverHelpers webDriverHelpers, SoftAssert softly) { FilesHelper.waitForFileToDownload(USER_ROLES_FILE_PATH, 30); FilesHelper.validateFileIsNotEmpty(USER_ROLES_FILE_PATH); }); + + And( + "^I check if the \"([^\"]*)\" user role exist and change it to enabled$", + (String userRole) -> { + webDriverHelpers.waitUntilIdentifiedElementIsPresent(USER_RIGHTS_INPUT); + webDriverHelpers.scrollInTable(20); + + if (webDriverHelpers.isElementVisibleWithTimeout(getUserRoleCaptionByText(userRole), 7)) { + webDriverHelpers.doubleClickOnWebElementBySelector(getUserRoleCaptionByText(userRole)); + TimeUnit.SECONDS.sleep(3); + webDriverHelpers.scrollToElement(DISCARD_BUTTON); + System.out.print("Zescrollowalem"); + if (webDriverHelpers.isElementVisibleWithTimeout(USER_ROLE_ENABLE_BUTTON, 7)) { + System.out.print("wszedlem do drugiego ifa"); + webDriverHelpers.scrollToElement(USER_ROLE_ENABLE_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(USER_ROLE_ENABLE_BUTTON); + webDriverHelpers.clickOnWebElementBySelector(SAVE_BUTTON); + } + } + }); } } diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/User.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/User.feature index 6cfe7ac8ec9..7c8ce860cf1 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/User.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/User.feature @@ -240,6 +240,9 @@ Feature: Create user Scenario: Edit and create user roles Given I log in as a Admin User And I click on the Users from navbar + And I click on User roles tab from User Management Page + And I check if the "TestNatUser" user role exist and change it to enabled + And I click on the Users from navbar And I check if there is any user with the "TestNatUser" role and change his role And I click on User roles tab from User Management Page And I check if the "TestNatUser" user role exist and delete it From bee6e2f3bb7f922695c22c6da80a77a327d02852 Mon Sep 17 00:00:00 2001 From: Levente Gal Date: Thu, 12 Jan 2023 09:11:44 +0200 Subject: [PATCH 109/166] #9759 Move functional information from toString to getCaption methods II - fix component columns --- .../symeda/sormas/ui/sormastosormas/CasePreviewGrid.java | 2 -- .../java/de/symeda/sormas/ui/utils/CaptionRenderer.java | 2 +- .../main/java/de/symeda/sormas/ui/utils/FilteredGrid.java | 7 ++++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/CasePreviewGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/CasePreviewGrid.java index 6bbc806acb0..dd996e246fd 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/CasePreviewGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/CasePreviewGrid.java @@ -125,8 +125,6 @@ protected void buildGrid() { getColumn(SormasToSormasCasePreview.REGION).setRenderer(new CaptionRenderer()); getColumn(SormasToSormasCasePreview.DISTRICT).setRenderer(new CaptionRenderer()); getColumn(SormasToSormasCasePreview.COMMUNITY).setRenderer(new CaptionRenderer()); - getColumn(SormasToSormasCasePreview.HEALTH_FACILITY).setRenderer(new CaptionRenderer()); - getColumn(SormasToSormasCasePreview.POINT_OF_ENTRY).setRenderer(new CaptionRenderer()); for (Column column : getColumns()) { column.setCaption( diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CaptionRenderer.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CaptionRenderer.java index d6dc93ad28c..ccd786038a2 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CaptionRenderer.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CaptionRenderer.java @@ -33,7 +33,7 @@ public JsonValue encode(Object value) { } if (!HasCaption.class.isAssignableFrom(value.getClass())) { - return super.encode(value.toString()); + return super.encode(value); } return super.encode(((HasCaption) value).buildCaption()); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FilteredGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FilteredGrid.java index 83958122d34..6909fe16fac 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FilteredGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FilteredGrid.java @@ -26,9 +26,7 @@ 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.UserDto; import de.symeda.sormas.api.user.UserRight; -import de.symeda.sormas.api.utils.HasCaption; import de.symeda.sormas.api.utils.SortProperty; import de.symeda.sormas.api.utils.criteria.BaseCriteria; import de.symeda.sormas.api.utils.pseudonymization.PseudonymizableIndexDto; @@ -218,7 +216,10 @@ public void setColumns(String... columnIds) { Arrays.asList(columnIds).forEach(columnId -> { if (!columnId.equals(ACTION_BTN_ID)) { - ((Column) getColumn(columnId)).setRenderer(new CaptionRenderer()); + Column column = getColumn(columnId); + if (column.getRenderer() == null) { + column.setRenderer(new CaptionRenderer()); + } } }); } From a5a9a478d163a14d7137263c45ee752787570c10 Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Thu, 12 Jan 2023 11:07:58 +0100 Subject: [PATCH 110/166] fix --- .../pages/application/configuration/CountriesTabPage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java index 5f87cfe9a22..11b49996a74 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java @@ -37,7 +37,7 @@ public class CountriesTabPage { public static final By COUNTRY_GRID_RESULTS_ROWS = By.cssSelector("[role=rowgroup] tr a"); public static final By NUMBER_OF_COUNTRIES = By.xpath( - "//div[@class='v-label v-widget bold v-label-bold vspace-top-none v-label-vspace-top-none align-right v-label-align-right v-label-undef-w']"); + "//div[@class='v-slot v-slot-bold v-slot-vspace-top-none v-slot-align-right v-align-right v-align-middle']"); public static final By COUNTRIES_TABLE_DATA = By.tagName("td"); public static final By COUNTRIES_TABLE_ROW = By.cssSelector("div.v-grid-tablewrapper tbody tr"); public static final By COUNTRIES_NAME_TABLE_ROW = From 87d9b1248de1f49cce9202e8423c83d8c19ab24b Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Thu, 12 Jan 2023 15:00:49 +0200 Subject: [PATCH 111/166] #11247 - [Persons] Travel entry information is not displayed in the 'Travel entry' card on a person page if the travel entry is outside the user's jurisdiction or of a different disease --- .../services/BaseTravelEntryService.java | 13 ++++++++++--- .../services/TravelEntryListService.java | 4 +--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/BaseTravelEntryService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/BaseTravelEntryService.java index bc40ad2be28..ce335df8e11 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/BaseTravelEntryService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/BaseTravelEntryService.java @@ -50,14 +50,21 @@ protected Predicate createUserFilterInternal(CriteriaBuilder cb, CriteriaQuery c } public Predicate createUserFilter(TravelEntryQueryContext qc) { + return createUserFilter(qc, true); + } + + public Predicate createUserFilter(TravelEntryQueryContext qc, boolean checkJurisdictionAndLimitedDisease) { User currentUser = getCurrentUser(); if (currentUser == null) { return null; } final CriteriaBuilder cb = qc.getCriteriaBuilder(); - Predicate filter = inJurisdictionOrOwned(qc); - if (currentUser.getLimitedDisease() != null) { - filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(qc.getRoot().get(Contact.DISEASE), currentUser.getLimitedDisease())); + Predicate filter = null; + if (checkJurisdictionAndLimitedDisease) { + filter = inJurisdictionOrOwned(qc); + if (currentUser.getLimitedDisease() != null) { + filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(qc.getRoot().get(Contact.DISEASE), currentUser.getLimitedDisease())); + } } return filter; } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/TravelEntryListService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/TravelEntryListService.java index 7d8ae915f94..f2e2b56df33 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/TravelEntryListService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/services/TravelEntryListService.java @@ -11,9 +11,7 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; -import de.symeda.sormas.api.EditPermissionType; import de.symeda.sormas.api.travelentry.TravelEntryListEntryDto; -import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; import de.symeda.sormas.backend.infrastructure.pointofentry.PointOfEntry; import de.symeda.sormas.backend.travelentry.TravelEntry; @@ -65,7 +63,7 @@ private Predicate buildListEntryCriteriaFilter(Long personId, Long caseId, Trave final CriteriaBuilder cb = travelEntryQueryContext.getCriteriaBuilder(); final From from = travelEntryQueryContext.getRoot(); - Predicate filter = createUserFilter(travelEntryQueryContext); + Predicate filter = createUserFilter(travelEntryQueryContext, false); if (personId != null) { filter = CriteriaBuilderHelper.and(cb, filter, cb.equal(from.get(TravelEntry.PERSON_ID), personId)); From 7c6e018d155f7b978c17e14f0f4dc5fb01d1d87c Mon Sep 17 00:00:00 2001 From: Razvan Date: Thu, 12 Jan 2023 22:21:58 +0200 Subject: [PATCH 112/166] #8554-CreateTestToCheckCaseRegionDistrictInTasks : created new automated test --- .../configuration/CountriesTabPage.java | 4 +- .../entities/services/api/CaseApiService.java | 2 + .../tasks/TaskManagementSteps.java | 40 +++++++++++++++++++ .../sanity/web/TaskManagementFilter.feature | 19 ++++++++- 4 files changed, 62 insertions(+), 3 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java index 3b6c796cf98..4113ad63839 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java @@ -36,8 +36,8 @@ public class CountriesTabPage { public static final By SUBCONTINENT_TABLE_VALUE = By.xpath("//table//tbody//tr[1]/td[4]"); public static final By COUNTRY_GRID_RESULTS_ROWS = By.cssSelector("[role=rowgroup] tr a"); public static final By NUMBER_OF_COUNTRIES = - By.xpath( - "//div[@class='v-label v-widget v-label-undef-w bold v-label-bold vspace-top-none v-label-vspace-top-none align-right v-label-align-right']"); + By.xpath( + "//div[@class='v-label v-widget v-label-undef-w bold v-label-bold vspace-top-none v-label-vspace-top-none align-right v-label-align-right']"); public static final By COUNTRIES_TABLE_DATA = By.tagName("td"); public static final By COUNTRIES_TABLE_ROW = By.cssSelector("div.v-grid-tablewrapper tbody tr"); public static final By COUNTRIES_NAME_TABLE_ROW = diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/CaseApiService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/CaseApiService.java index 0ac3f0cf03a..fb5743b781f 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/CaseApiService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/api/CaseApiService.java @@ -61,12 +61,14 @@ public Case buildGeneratedCase(Person person) { .build()) .district( District.builder() + .caption(DistrictsValues.VoreingestellterLandkreis.getName()) .uuid( environmentManager.getDistrictUUID( DistrictsValues.VoreingestellterLandkreis.getName())) .build()) .region( Region.builder() + .caption(RegionsValues.VoreingestellteBundeslander.getName()) .uuid( environmentManager.getRegionUUID( RegionsValues.VoreingestellteBundeslander.getName())) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/tasks/TaskManagementSteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/tasks/TaskManagementSteps.java index 8cddad21ad0..c29fffcc5e5 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/tasks/TaskManagementSteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/tasks/TaskManagementSteps.java @@ -146,6 +146,28 @@ public TaskManagementSteps( COMMENTS_ON_EXECUTION_TEXTAREA); }); + When( + "^I search task by last Case created via API UUID$", + () -> { + String lastCreatedCaseUUID = apiState.getCreatedCase().getUuid(); + webDriverHelpers.waitUntilIdentifiedElementIsVisibleAndClickable( + GENERAL_SEARCH_INPUT, 50); + webDriverHelpers.fillAndSubmitInWebElement(GENERAL_SEARCH_INPUT, lastCreatedCaseUUID); + webDriverHelpers.waitForPageLoadingSpinnerToDisappear(50); + + // By lastTaskEditButton = + // By.xpath( + // String.format( + // EDIT_BUTTON_XPATH_BY_TEXT, + // CreateNewTaskSteps.task.getCommentsOnTask())); + // + // webDriverHelpers.waitUntilIdentifiedElementIsVisibleAndClickable(lastTaskEditButton, + // 20); + // webDriverHelpers.clickOnWebElementBySelector(lastTaskEditButton); + // webDriverHelpers.waitUntilIdentifiedElementIsVisibleAndClickable( + // COMMENTS_ON_EXECUTION_TEXTAREA); + }); + When( "^I am checking if the associated linked event appears in task management and click on it$", () -> { @@ -178,6 +200,24 @@ public TaskManagementSteps( }); softly.assertAll(); }); + + When( + "^I check displayed tasks District and Region are taken from API created Case$", + () -> { + taskTableRows.forEach( + data -> { + softly.assertEquals( + data.getRegion(), + apiState.getCreatedCase().getRegion().getCaption(), + "Task region is not the same with Case region"); + softly.assertEquals( + data.getDistrict(), + apiState.getCreatedCase().getDistrict().getCaption(), + "Task district is not the same with Case district"); + }); + softly.assertAll(); + }); + When( "^I check displayed task's context of first result is ([^\"]*)$", (String taskContext) -> { diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/TaskManagementFilter.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/TaskManagementFilter.feature index d3aa95bba35..1d7cc96c477 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/TaskManagementFilter.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/TaskManagementFilter.feature @@ -31,4 +31,21 @@ Feature: Tasks filtering functionalities | pending | | done | | removed | - | not executable | \ No newline at end of file + | not executable | + + @#8554 @env_main + Scenario: Verify task displays District and Region in results grid from Case used to create the task + Given API: I create a new person + Then API: I check that POST call body is "OK" + And API: I check that POST call status code is 200 + Then API: I create a new case + Then API: I check that POST call body is "OK" + And API: I check that POST call status code is 200 + Given I log in as a Surveillance Officer + Then I navigate to the last created case via the url + And I click on New Task from Case page + And I create a new task with "Nat USER" as a assigned user + Then I click on the Tasks button from navbar + And I search task by last Case created via API UUID + And I collect the task column objects + And I check displayed tasks District and Region are taken from API created Case \ No newline at end of file From 99282255472b61ba897b1852b60fb1e0ef3693e8 Mon Sep 17 00:00:00 2001 From: Levente Gal Date: Fri, 13 Jan 2023 12:17:49 +0200 Subject: [PATCH 113/166] #9759 Move functional information from toString to getCaption methods II - fixed rendering items in the user role template selectors --- .../symeda/sormas/api/user/UserRoleDto.java | 6 +++++- .../sormas/ui/user/UserRoleFormHelper.java | 20 ++++++++++--------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/user/UserRoleDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/user/UserRoleDto.java index ba13db32f52..6b0be932df1 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/user/UserRoleDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/user/UserRoleDto.java @@ -168,7 +168,6 @@ public static Set getUserRights(Collection userRoles) { return userRoles != null ? userRoles.stream().flatMap(role -> role.getUserRights().stream()).collect(Collectors.toSet()) : null; } - public DefaultUserRole getLinkedDefaultUserRole() { return linkedDefaultUserRole; } @@ -208,6 +207,11 @@ public void setNotificationTypes(NotificationTypes notificationTypes) { this.emailNotificationTypes = notificationTypes.email; } + @Override + public String buildCaption() { + return caption; + } + @SuppressWarnings("serial") public static class UserRoleValidationException extends ValidationException { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserRoleFormHelper.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserRoleFormHelper.java index 8441e10a414..1120a118213 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserRoleFormHelper.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserRoleFormHelper.java @@ -46,13 +46,12 @@ public static void createFieldDependencies(AbstractForm form) { UserRoleDto.JURISDICTION_LEVEL, Arrays.asList(JurisdictionLevel.COMMUNITY, JurisdictionLevel.HEALTH_FACILITY), true); - FieldHelper - .setDisabledWhen( - fieldGroup, - UserRoleDto.JURISDICTION_LEVEL, - JurisdictionLevel.HEALTH_FACILITY, - UserRoleDto.HAS_OPTIONAL_HEALTH_FACILITY, - false); + FieldHelper.setDisabledWhen( + fieldGroup, + UserRoleDto.JURISDICTION_LEVEL, + JurisdictionLevel.HEALTH_FACILITY, + UserRoleDto.HAS_OPTIONAL_HEALTH_FACILITY, + false); FieldHelper .setDisabledWhen(fieldGroup, UserRoleDto.JURISDICTION_LEVEL, JurisdictionLevel.POINT_OF_ENTRY, UserRoleDto.PORT_HEALTH_USER, false); fieldGroup.getField(UserRoleDto.JURISDICTION_LEVEL).addValueChangeListener(e -> { @@ -66,8 +65,11 @@ public static void createFieldDependencies(AbstractForm form) { } public static void setTemplateRoleItems(ComboBox templateRoleCombo) { - List existingUserRoles = - FacadeProvider.getUserRoleFacade().getAllActive().stream().sorted(Comparator.comparing(UserRoleDto::getCaption)).collect(Collectors.toList()); + List existingUserRoles = FacadeProvider.getUserRoleFacade() + .getAllActive() + .stream() + .sorted(Comparator.comparing(UserRoleDto::getCaption)) + .collect(Collectors.toList()); List defaultUserRoles = FacadeProvider.getUserRoleFacade() .getDefaultUserRolesAsDto() .stream() From 2cf8f52a55fcdf1764be2d2eeaa2255b55a86dd3 Mon Sep 17 00:00:00 2001 From: Carina Paul <47103965+carina29@users.noreply.github.com> Date: Fri, 13 Jan 2023 12:32:01 +0200 Subject: [PATCH 114/166] #11313 - fix item counter in case of bulk edit mode (#11341) --- .../de/symeda/sormas/ui/caze/CasesView.java | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasesView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasesView.java index 3ec845d756f..d8d6708256e 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasesView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CasesView.java @@ -169,21 +169,21 @@ public CasesView() { criteria = ViewModelProviders.of(CasesView.class).get(CaseCriteria.class, getDefaultCriteria()); - if (CasesViewType.FOLLOW_UP_VISITS_OVERVIEW.equals(viewConfiguration.getViewType())) { + if (isFollowUpVisitsOverviewType()) { if (criteria.getFollowUpVisitsInterval() == null) { criteria.setFollowUpVisitsInterval(followUpRangeInterval); } grid = new CaseFollowUpGrid(criteria, getClass()); } else { criteria.followUpUntilFrom(null); - grid = CasesViewType.DETAILED.equals(viewConfiguration.getViewType()) ? new CaseGridDetailed(criteria) : new CaseGrid(criteria); + grid = isDetailedViewType() ? new CaseGridDetailed(criteria) : new CaseGrid(criteria); } final VerticalLayout gridLayout = new VerticalLayout(); gridLayout.addComponent(createFilterBar()); gridLayout.addComponent(createStatusFilterBar()); gridLayout.addComponent(grid); - if (CasesViewType.FOLLOW_UP_VISITS_OVERVIEW.equals(viewConfiguration.getViewType())) { + if (isFollowUpVisitsOverviewType()) { gridLayout.addComponent(createFollowUpLegend()); } @@ -552,6 +552,18 @@ private void enterBulkEditMode() { ((AbstractCaseGrid) grid).reload(); } + private boolean isDefaultViewType() { + return viewConfiguration.getViewType() == CasesViewType.DEFAULT; + } + + private boolean isDetailedViewType() { + return viewConfiguration.getViewType() == CasesViewType.DETAILED; + } + + private boolean isFollowUpVisitsOverviewType() { + return viewConfiguration.getViewType() == CasesViewType.FOLLOW_UP_VISITS_OVERVIEW; + } + public VerticalLayout createFilterBar() { VerticalLayout filterLayout = new VerticalLayout(); filterLayout.setSpacing(false); @@ -569,7 +581,7 @@ public VerticalLayout createFilterBar() { navigateTo(null, true); }); filterForm.addApplyHandler(e -> { - if (CasesViewType.FOLLOW_UP_VISITS_OVERVIEW.equals(viewConfiguration.getViewType())) { + if (isFollowUpVisitsOverviewType()) { ((CaseFollowUpGrid) grid).reload(); } else { ((AbstractCaseGrid) grid).reload(); @@ -578,7 +590,7 @@ public VerticalLayout createFilterBar() { filterLayout.addComponent(filterForm); // Follow-up overview scrolling - if (CasesViewType.FOLLOW_UP_VISITS_OVERVIEW.equals(viewConfiguration.getViewType())) { + if (isFollowUpVisitsOverviewType()) { HorizontalLayout actionButtonsLayout = new HorizontalLayout(); actionButtonsLayout.setSpacing(true); @@ -830,12 +842,19 @@ public void enter(ViewChangeEvent event) { criteria.fromUrlParams(params); } - if (viewConfiguration.isInEagerMode() && viewConfiguration.getViewType() != CasesViewType.FOLLOW_UP_VISITS_OVERVIEW) { + if (viewConfiguration.isInEagerMode() && !isFollowUpVisitsOverviewType()) { AbstractCaseGrid caseGrid = (AbstractCaseGrid) this.grid; caseGrid.setEagerDataProvider(); } updateFilterComponents(); + if (isDefaultViewType()) { + ((CaseGrid) grid).reload(); + } else if (isFollowUpVisitsOverviewType()) { + ((CaseFollowUpGrid) grid).reload(); + } else { + ((CaseGridDetailed) grid).reload(); + } } public List getSelectedCases(AbstractCaseGrid caseGrid) { From 8979e9892fa13fe30c0708451c087951b202c928 Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Fri, 13 Jan 2023 14:29:29 +0100 Subject: [PATCH 115/166] germany western europe --- .../org/sormas/e2etests/entities/services/ContactService.java | 2 +- .../e2etests/entities/services/ExposureDetailsService.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/ContactService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/ContactService.java index 85bb6029521..9be656deb9a 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/ContactService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/ContactService.java @@ -279,7 +279,7 @@ public Exposure buildGeneratedExposureDataContactForRandomInputs() { .typeOfPlace(TypeOfPlace.HOME) .typeOfPlaceDetails(faker.address().fullAddress()) .continent("Europe") - .subcontinent("Central Europe") + .subcontinent("Western Europe") .country("Germany") .exposureRegion(RegionsValues.VoreingestellteBundeslander.getName()) .district(DistrictsValues.VoreingestellterLandkreis.getName()) diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/ExposureDetailsService.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/ExposureDetailsService.java index 1a77e4fd802..63e83ada27c 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/ExposureDetailsService.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/entities/services/ExposureDetailsService.java @@ -41,7 +41,7 @@ public ExposureDetails buildInputExposureDetails() { .handlingSamples(YesNoUnknownOptions.YES.toString()) .typeOfPlace("Home") .continent("Europe") - .subcontinent("Central Europe") + .subcontinent("Western Europe") .country("Austria") .exposureRegion("") .district("") From 41a2ea30ef613272f1b6330b3a4540911f76e02b Mon Sep 17 00:00:00 2001 From: Levente Gal <62599627+leventegal-she@users.noreply.github.com> Date: Fri, 13 Jan 2023 16:02:14 +0200 Subject: [PATCH 116/166] #10535 S2S_layout share directory - make action and comment columns fixed so the table layout doesn't change so much when changing the filters (#11324) Co-authored-by: Levente Gal --- .../symeda/sormas/ui/sormastosormas/ShareRequestGrid.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/ShareRequestGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/ShareRequestGrid.java index 9eb448e0131..b0e8888daec 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/ShareRequestGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/sormastosormas/ShareRequestGrid.java @@ -97,7 +97,11 @@ private void initGridColumns() { .setRenderer(new DateRenderer(DateHelper.getLocalDateTimeFormat(I18nProperties.getUserLanguage()))); getColumn(ShareRequestIndexDto.OWNERSHIP_HANDED_OVER).setRenderer(new BooleanRenderer()); - getColumn(ShareRequestIndexDto.COMMENT).setDescriptionGenerator((DescriptionGenerator) item -> item.getComment()); + getColumn(COLUMN_ACTIONS).setWidth(250); + + Column commentColumn = getColumn(ShareRequestIndexDto.COMMENT); + commentColumn.setDescriptionGenerator((DescriptionGenerator) ShareRequestIndexDto::getComment); + commentColumn.setWidth(300); for (Column column : getColumns()) { column.setCaption( From c99833b6a2e9a9794715b8b24760e248c08abdf8 Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Fri, 13 Jan 2023 16:03:05 +0200 Subject: [PATCH 117/166] #11344 - [Areas - Configuration Directory] Error message appears when trying to access the 'Areas' tab --- .../ui/configuration/infrastructure/AreasView.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/AreasView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/AreasView.java index cb8b80e87a3..e25eae4530c 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/AreasView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/AreasView.java @@ -2,6 +2,9 @@ import static com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; +import java.util.ArrayList; +import java.util.List; + import com.vaadin.icons.VaadinIcons; import com.vaadin.server.FileDownloader; import com.vaadin.server.StreamResource; @@ -177,7 +180,11 @@ private HorizontalLayout createFilterBar() { filterRelevanceStatus.setId("relevanceStatus"); filterRelevanceStatus.setWidth(220, Unit.PERCENTAGE); filterRelevanceStatus.setEmptySelectionAllowed(false); - filterRelevanceStatus.setItems((EntityRelevanceStatus[]) EntityRelevanceStatus.getAllExceptDeleted()); + List items = new ArrayList<>(); + for (Object o : EntityRelevanceStatus.getAllExceptDeleted()) { + items.add((EntityRelevanceStatus) o); + } + filterRelevanceStatus.setItems(items); filterRelevanceStatus.setItemCaptionGenerator(status -> { switch (status) { case ACTIVE: @@ -223,8 +230,7 @@ private HorizontalLayout createFilterBar() { }, EntityRelevanceStatus.ARCHIVED.equals(criteria.getRelevanceStatus()))); - dropdownBulkOperations - .setVisible(isBulkOperationsDropdownVisible()); + dropdownBulkOperations.setVisible(isBulkOperationsDropdownVisible()); actionButtonsLayout.addComponent(dropdownBulkOperations); } } From dbd4318b362a9a977b6559cd2e0aa38445f8f4b5 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Fri, 13 Jan 2023 18:58:09 +0100 Subject: [PATCH 118/166] fixes in scenario --- .../pages/application/mSers/MSersDirectoryPage.java | 7 +++++++ .../steps/web/application/mSers/MSersDirectorySteps.java | 7 ++++--- .../src/test/resources/features/sanity/web/mSERS.feature | 6 ++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/mSers/MSersDirectoryPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/mSers/MSersDirectoryPage.java index 35cc950db62..cdcc61da110 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/mSers/MSersDirectoryPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/mSers/MSersDirectoryPage.java @@ -36,6 +36,13 @@ public static By getEditButtonByIndex(int idx) { idx)); } + public static By getDeleteButtonByIndex(int idx) { + return By.xpath( + String.format( + "(//tr[contains(@class,'v-grid-row-has-data')]//td[14]//span[@class='v-icon Vaadin-Icons'])[%x]", + idx)); + } + public static final By REGION_FILTER_COMBOBOX = By.cssSelector("#region div"); public static final By DISTRICT_FILTER_COMBOBOX = By.cssSelector("#district div"); public static final By AGGREGATED_REPORT_APPLY_FILTER_BUTTON = diff --git a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/mSers/MSersDirectorySteps.java b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/mSers/MSersDirectorySteps.java index 15fc95cbd1c..870cc46071e 100644 --- a/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/mSers/MSersDirectorySteps.java +++ b/sormas-e2e-tests/src/test/java/org/sormas/e2etests/steps/web/application/mSers/MSersDirectorySteps.java @@ -22,13 +22,13 @@ import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.REPORT_DATA_BUTTON; import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.RESULT_IN_GRID; import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.SHOW_ROWS_FOR_DISEASES_LABEL; -import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.THIRD_ROW_EDIT_ICON; import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.YEAR_FROM_COMOBOX; import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.YEAR_FROM_INPUT; import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.YEAR_TO_COMOBOX; import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.YEAR_TO_INPUT; import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.getAgeGroupByResultNumber; import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.getColumnSelectorByName; +import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.getDeleteButtonByIndex; import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.getEditButtonByIndex; import static org.sormas.e2etests.pages.application.mSers.MSersDirectoryPage.getNumberOfSuspectedCasesByIndex; import static org.sormas.e2etests.steps.web.application.mSers.CreateNewAggregateReportSteps.duplicateReportWithJurisdiction; @@ -144,10 +144,10 @@ public MSersDirectorySteps( () -> { webDriverHelpers.waitForPageLoadingSpinnerToDisappear(70); softly.assertTrue( - webDriverHelpers.isElementVisibleWithTimeout(DELETE_ICON, 5), + webDriverHelpers.isElementPresent(getDeleteButtonByIndex(1)), "Delete icon is not visible"); softly.assertTrue( - webDriverHelpers.isElementVisibleWithTimeout(THIRD_ROW_EDIT_ICON, 5), + webDriverHelpers.isElementPresent(getEditButtonByIndex(1)), "Edit icon is not visible"); softly.assertAll(); }); @@ -169,6 +169,7 @@ public MSersDirectorySteps( "I set Epi week from filter to {string} in mSers directory page", (String year) -> { TimeUnit.SECONDS.sleep(1); + webDriverHelpers.selectFromCombobox(EPI_WEEK_FROM_COMOBOX, ""); webDriverHelpers.selectFromCombobox(EPI_WEEK_FROM_COMOBOX, year); }); When( diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/mSERS.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/mSERS.feature index 0bc6f127996..d5cb38f4432 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/mSERS.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/mSERS.feature @@ -62,6 +62,12 @@ Feature: mSERS functionalities Scenario:Test Add a view to list aggregate report data and to highlight duplicates Given I log in as a Surveillance Officer When I click on the mSERS button from navbar + And I navigate to Report data tab + And I set Epi Year from filter to "2004" in mSers directory page + Then I set Epi week from filter to "Wk 1-2004 (12/29 - 1/4)" in mSers directory page + And I click on the APPLY FILTERS button + And I check aggregate reports and delete them if they are listed + When I click on the mSERS button from navbar When I click on the NEW AGGREGATE REPORT button Then I click on SPECIFY Radiobutton in Create Aggregated Report form And I fill a new aggregate report with specific data for duplicates From ab3a8b53fed029be915a16cd8f3f81fbc7b02e2f Mon Sep 17 00:00:00 2001 From: Carina Paul <47103965+carina29@users.noreply.github.com> Date: Mon, 16 Jan 2023 08:46:02 +0200 Subject: [PATCH 119/166] #11337 - fix NPE (#11347) --- .../java/de/symeda/sormas/ui/exposure/ExposuresField.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/exposure/ExposuresField.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/exposure/ExposuresField.java index 89faf90f54d..6df23badf11 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/exposure/ExposuresField.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/exposure/ExposuresField.java @@ -227,11 +227,16 @@ private void addGeneratedColumns(Table table) { table.addGeneratedColumn(COLUMN_SOURCE_CASE_NAME, (Table.ColumnGenerator) (source, itemId, columnId) -> { ExposureDto exposure = (ExposureDto) itemId; return !isPseudonymized - ? DataHelper.toStringNullable(exposure.getContactToCase() != null ? exposure.getContactToCase().getCaseName().buildCaption() : "") + ? DataHelper + .toStringNullable(isCaseNameExisting(exposure.getContactToCase()) ? exposure.getContactToCase().getCaseName().buildCaption() : "") : I18nProperties.getCaption(Captions.inaccessibleValue); }); } + private boolean isCaseNameExisting(ContactReferenceDto contactToCase) { + return contactToCase != null && contactToCase.getCaseName() != null; + } + @Override protected boolean isEmpty(ExposureDto entry) { return false; From 4dd7b689a8889b906297e08127abc8625a089789 Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Mon, 16 Jan 2023 11:55:10 +0200 Subject: [PATCH 120/166] #11344 - [Areas - Configuration Directory] Error message appears when trying to access the 'Areas' tab --- .../de/symeda/sormas/api/EntityRelevanceStatus.java | 10 +++++++--- .../ui/configuration/infrastructure/AreasView.java | 9 +-------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/EntityRelevanceStatus.java b/sormas-api/src/main/java/de/symeda/sormas/api/EntityRelevanceStatus.java index 4d7a95e9bab..df0f3e7c925 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/EntityRelevanceStatus.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/EntityRelevanceStatus.java @@ -1,6 +1,7 @@ package de.symeda.sormas.api; import java.util.Arrays; +import java.util.stream.Collectors; import de.symeda.sormas.api.i18n.I18nProperties; @@ -16,7 +17,10 @@ public String toString() { return I18nProperties.getEnumCaption(this); } - public static Object[] getAllExceptDeleted() { - return Arrays.stream(EntityRelevanceStatus.values()).filter(val -> val != EntityRelevanceStatus.DELETED).toArray(); - }; + public static EntityRelevanceStatus[] getAllExceptDeleted() { + return Arrays.stream(EntityRelevanceStatus.values()) + .filter(val -> val != EntityRelevanceStatus.DELETED) + .collect(Collectors.toList()) + .toArray(new EntityRelevanceStatus[] {}); + } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/AreasView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/AreasView.java index e25eae4530c..316c5fcedb8 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/AreasView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/infrastructure/AreasView.java @@ -2,9 +2,6 @@ import static com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; -import java.util.ArrayList; -import java.util.List; - import com.vaadin.icons.VaadinIcons; import com.vaadin.server.FileDownloader; import com.vaadin.server.StreamResource; @@ -180,11 +177,7 @@ private HorizontalLayout createFilterBar() { filterRelevanceStatus.setId("relevanceStatus"); filterRelevanceStatus.setWidth(220, Unit.PERCENTAGE); filterRelevanceStatus.setEmptySelectionAllowed(false); - List items = new ArrayList<>(); - for (Object o : EntityRelevanceStatus.getAllExceptDeleted()) { - items.add((EntityRelevanceStatus) o); - } - filterRelevanceStatus.setItems(items); + filterRelevanceStatus.setItems(EntityRelevanceStatus.getAllExceptDeleted()); filterRelevanceStatus.setItemCaptionGenerator(status -> { switch (status) { case ACTIVE: From 8a69331b92c8bd469908c5b96e506e79603dd7be Mon Sep 17 00:00:00 2001 From: Carina Paul Date: Mon, 16 Jan 2023 12:41:57 +0200 Subject: [PATCH 121/166] #11263 - delete unnecessary style --- .../de/symeda/sormas/ui/samples/SampleGridFilterForm.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleGridFilterForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleGridFilterForm.java index d62e9f19b5e..696a530846b 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleGridFilterForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/SampleGridFilterForm.java @@ -5,11 +5,9 @@ import java.util.Date; import java.util.stream.Stream; -import com.vaadin.icons.VaadinIcons; import com.vaadin.shared.ui.ContentMode; import com.vaadin.ui.CustomLayout; import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.Label; import com.vaadin.v7.data.Property; import com.vaadin.v7.ui.ComboBox; import com.vaadin.v7.ui.Field; @@ -29,7 +27,6 @@ import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.api.utils.EpiWeek; import de.symeda.sormas.ui.utils.AbstractFilterForm; -import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.EpiWeekAndDateFilterComponent; import de.symeda.sormas.ui.utils.FieldConfiguration; @@ -112,7 +109,6 @@ protected void addFields() { FieldConfiguration .withCaptionAndPixelSized(SampleCriteria.CASE_CODE_ID_LIKE, I18nProperties.getString(Strings.promptSamplesSearchField), 200)); searchField.setDescription(I18nProperties.getString(Strings.promptSamplesSearchField), ContentMode.HTML); - searchField.addStyleNames(CssStyles.VSPACE_TOP_4, CssStyles.HSPACE_RIGHT_4); searchField.setNullRepresentation(""); } From dfb9d31fdb6ff95ab181301f46f4491b49639d0e Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Mon, 16 Jan 2023 11:44:06 +0100 Subject: [PATCH 122/166] enable the gradle configuration cache --- sormas-e2e-tests/gradle.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/sormas-e2e-tests/gradle.properties b/sormas-e2e-tests/gradle.properties index 954233972cc..9dbcf7de08b 100644 --- a/sormas-e2e-tests/gradle.properties +++ b/sormas-e2e-tests/gradle.properties @@ -18,6 +18,7 @@ org.gradle.daemon=true org.gradle.parallel=true +org.gradle.unsafe.configuration-cache=true allureVersion=2.10.0 allureJavaAdapterVersion=1.5.4 cucumberVersion=4.3.0 From 23eee20e7178a85842c47ba20d857a42ed2f9ced Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Mon, 16 Jan 2023 12:19:53 +0100 Subject: [PATCH 123/166] enable build cache and increase heap size --- sormas-e2e-tests/gradle.properties | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sormas-e2e-tests/gradle.properties b/sormas-e2e-tests/gradle.properties index 9dbcf7de08b..c260d60a93f 100644 --- a/sormas-e2e-tests/gradle.properties +++ b/sormas-e2e-tests/gradle.properties @@ -19,6 +19,8 @@ org.gradle.daemon=true org.gradle.parallel=true org.gradle.unsafe.configuration-cache=true +org.gradle.caching=true +org.gradle.jvmargs=-Xmx1024M allureVersion=2.10.0 allureJavaAdapterVersion=1.5.4 cucumberVersion=4.3.0 From 15575b71ade7b7f30061072533ceb101249e6329 Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Mon, 16 Jan 2023 14:47:51 +0200 Subject: [PATCH 124/166] #9742 - Bad formatting of error message for missing information aroundVesiculopustular rash --- .../utils/CommitDiscardWrapperComponent.java | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CommitDiscardWrapperComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CommitDiscardWrapperComponent.java index efbbf94e014..c285f273bfb 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CommitDiscardWrapperComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CommitDiscardWrapperComponent.java @@ -48,6 +48,7 @@ import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.ValoTheme; import com.vaadin.v7.data.Buffered; +import com.vaadin.v7.data.Validator; import com.vaadin.v7.data.Validator.InvalidValueException; import com.vaadin.v7.data.fieldgroup.FieldGroup; import com.vaadin.v7.data.fieldgroup.FieldGroup.CommitException; @@ -131,6 +132,8 @@ public static interface DeleteWithDetailsListener { private boolean shortcutsEnabled = false; protected transient List actions; + private List tempCauses; + protected CommitDiscardWrapperComponent() { } @@ -434,7 +437,10 @@ public Button getDeleteWithReasonOrUndeleteButton(String entityName, boolean del deleteButton = buildDeleteButton(() -> { if (!deleted) { DeletableUtils.showDeleteWithReasonPopup( - String.format(I18nProperties.getString(Strings.confirmationDeleteEntityWithDetails), entityName, details != null ? details : ""), + String.format( + I18nProperties.getString(Strings.confirmationDeleteEntityWithDetails), + entityName, + details != null ? details : ""), this::onDeleteWithReason); } else { onDeleteWithReason(null); @@ -594,7 +600,11 @@ public boolean commitAndHandle() { htmlMsg.append(ex.getHtmlMessage()); } else { - InvalidValueException[] causes = ex.getCauses(); + InvalidValueException[] causes; + tempCauses = new ArrayList<>(); + extractCauses(ex.getCauses()); + causes = tempCauses.toArray(new InvalidValueException[] {}); + if (causes != null) { InvalidValueException firstCause = null; @@ -645,6 +655,16 @@ public boolean commitAndHandle() { } } + public void extractCauses(InvalidValueException[] causes) { + for (InvalidValueException cause : causes) { + if (cause.getCauses().length > 1) { + extractCauses(cause.getCauses()); + } else { + tempCauses.add(cause); + } + } + } + @Override public void discard() { if (fieldGroups != null) { From cd2949260195c8d9aaadeaadbd130c377d64f1f4 Mon Sep 17 00:00:00 2001 From: Razvan Date: Mon, 16 Jan 2023 16:35:05 +0200 Subject: [PATCH 125/166] #11306-FixNewUserRoleValidationTest : linked issue --- .../src/test/resources/features/sanity/web/User.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/test/resources/features/sanity/web/User.feature b/sormas-e2e-tests/src/test/resources/features/sanity/web/User.feature index 7c8ce860cf1..9c598c8fe4f 100644 --- a/sormas-e2e-tests/src/test/resources/features/sanity/web/User.feature +++ b/sormas-e2e-tests/src/test/resources/features/sanity/web/User.feature @@ -338,7 +338,7 @@ Feature: Create user And I confirm user role deletion And I click on User Management tab from User Roles Page - @#10422 @env_main @ignore + @#10422 @env_main @ignore @issue=9759 Scenario: Validate newly created user role is present in filtering options Given I log in as a Admin User And I click on the Users from navbar From 808fd512c5c6d116aa211bb128de2e3df4cde9b5 Mon Sep 17 00:00:00 2001 From: Levente Gal Date: Mon, 16 Jan 2023 20:46:23 +0200 Subject: [PATCH 126/166] #9759 Move functional information from toString to getCaption methods II - fixed rendering grid items --- .../sormas/ui/user/UserRoleFormHelper.java | 1 - .../ui/utils/ComboBoxWithPlaceholder.java | 27 ------------------- .../symeda/sormas/ui/utils/FilteredGrid.java | 3 ++- .../utils/SormasDefaultConverterFactory.java | 10 +++++++ 4 files changed, 12 insertions(+), 29 deletions(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserRoleFormHelper.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserRoleFormHelper.java index 1120a118213..5f351b7da94 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserRoleFormHelper.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/user/UserRoleFormHelper.java @@ -81,7 +81,6 @@ public static void setTemplateRoleItems(ComboBox templateRoleCombo) { templateItems.addAll(defaultUserRoles); FieldHelper.updateItems(templateRoleCombo, templateItems); - templateItems.forEach(t -> templateRoleCombo.setItemCaption(t, t.getCaption())); } private static String defaultCaptionExtension() { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/ComboBoxWithPlaceholder.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/ComboBoxWithPlaceholder.java index 54641a0b769..d4c80540011 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/ComboBoxWithPlaceholder.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/ComboBoxWithPlaceholder.java @@ -15,7 +15,6 @@ package de.symeda.sormas.ui.utils; -import java.util.Collection; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; @@ -24,44 +23,18 @@ import com.vaadin.v7.ui.ComboBox; import de.symeda.sormas.api.ReferenceDto; -import de.symeda.sormas.api.utils.HasCaption; public class ComboBoxWithPlaceholder extends ComboBox { private static final long serialVersionUID = 27751677500982303L; PlaceholderReferenceDto placeholder = null; - private boolean ignoreDirtyMarkingOnGetOfHasCaption = false; public ComboBoxWithPlaceholder() { super(); this.setFilteringMode(FilteringMode.CONTAINS); } - @Override - public String getItemCaption(Object itemId) { - if (itemId instanceof HasCaption) { - ignoreDirtyMarkingOnGetOfHasCaption = true; - this.setItemCaption(itemId, ((HasCaption) itemId).buildCaption()); - ignoreDirtyMarkingOnGetOfHasCaption = false; - } - return super.getItemCaption(itemId); - } - - public void markAsDirty() { - if (!ignoreDirtyMarkingOnGetOfHasCaption) { - super.markAsDirty(); - } - } - - @Override - public void addItems(Collection itemIds) throws UnsupportedOperationException { - super.addItems(itemIds); - for (Object item : itemIds) { - this.setItemCaption(item, item instanceof HasCaption ? ((HasCaption) item).buildCaption() : item.toString()); - } - } - @Override public boolean removeAllItems() throws UnsupportedOperationException { AtomicBoolean retVal = new AtomicBoolean(false); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FilteredGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FilteredGrid.java index 6909fe16fac..fd6bd33af13 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FilteredGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FilteredGrid.java @@ -22,6 +22,7 @@ import com.vaadin.ui.Grid; import com.vaadin.ui.Label; import com.vaadin.ui.renderers.HtmlRenderer; +import com.vaadin.ui.renderers.TextRenderer; import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.i18n.I18nProperties; @@ -217,7 +218,7 @@ public void setColumns(String... columnIds) { Arrays.asList(columnIds).forEach(columnId -> { if (!columnId.equals(ACTION_BTN_ID)) { Column column = getColumn(columnId); - if (column.getRenderer() == null) { + if (column.getRenderer() == null || TextRenderer.class.isAssignableFrom(column.getRenderer().getClass())) { column.setRenderer(new CaptionRenderer()); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/SormasDefaultConverterFactory.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/SormasDefaultConverterFactory.java index 4dc1a218836..bdd11916b81 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/SormasDefaultConverterFactory.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/SormasDefaultConverterFactory.java @@ -24,6 +24,8 @@ import com.vaadin.v7.data.util.converter.DefaultConverterFactory; import com.vaadin.v7.data.util.converter.StringToEnumConverter; +import de.symeda.sormas.api.utils.HasCaption; + @SuppressWarnings("serial") public final class SormasDefaultConverterFactory extends DefaultConverterFactory { @@ -45,6 +47,14 @@ public String convertToPresentation(Enum value, Class targetTy return SormasDefaultConverterFactory.enumToString(value, locale); } }; + } else if (HasCaption.class.isAssignableFrom(sourceType)) { + return new StringToAnythingConverter((Class) sourceType) { + + @Override + public String convertToPresentation(HasCaption value, Class targetType, Locale locale) throws ConversionException { + return value != null ? value.buildCaption() : null; + } + }; } return super.createStringConverter(sourceType); } From 944a7fdad0e668f014a67bf1017a13ec3261f5e6 Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Tue, 17 Jan 2023 10:36:44 +0100 Subject: [PATCH 127/166] org.gradle.unsafe.configuration-cache=false --- sormas-e2e-tests/gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/gradle.properties b/sormas-e2e-tests/gradle.properties index c260d60a93f..41c31eea234 100644 --- a/sormas-e2e-tests/gradle.properties +++ b/sormas-e2e-tests/gradle.properties @@ -18,7 +18,7 @@ org.gradle.daemon=true org.gradle.parallel=true -org.gradle.unsafe.configuration-cache=true +#org.gradle.unsafe.configuration-cache=true org.gradle.caching=true org.gradle.jvmargs=-Xmx1024M allureVersion=2.10.0 From e5e8233e12586131dba126587cc173f69778ca2c Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Tue, 17 Jan 2023 10:46:48 +0100 Subject: [PATCH 128/166] org.gradle.caching=false --- sormas-e2e-tests/gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/gradle.properties b/sormas-e2e-tests/gradle.properties index 41c31eea234..24426f1aae9 100644 --- a/sormas-e2e-tests/gradle.properties +++ b/sormas-e2e-tests/gradle.properties @@ -19,7 +19,7 @@ org.gradle.daemon=true org.gradle.parallel=true #org.gradle.unsafe.configuration-cache=true -org.gradle.caching=true +#org.gradle.caching=true org.gradle.jvmargs=-Xmx1024M allureVersion=2.10.0 allureJavaAdapterVersion=1.5.4 From cceb5c8158e7d7bfb2838e2d9e9dcd589657bd33 Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Tue, 17 Jan 2023 11:52:26 +0200 Subject: [PATCH 129/166] #9742 - Bad formatting of error message for missing information aroundVesiculopustular rash --- .../ui/utils/CommitDiscardWrapperComponent.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CommitDiscardWrapperComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CommitDiscardWrapperComponent.java index c285f273bfb..e0dad81f599 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CommitDiscardWrapperComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CommitDiscardWrapperComponent.java @@ -600,10 +600,7 @@ public boolean commitAndHandle() { htmlMsg.append(ex.getHtmlMessage()); } else { - InvalidValueException[] causes; - tempCauses = new ArrayList<>(); - extractCauses(ex.getCauses()); - causes = tempCauses.toArray(new InvalidValueException[] {}); + InvalidValueException[] causes = getAllCauses(ex.getCauses()); if (causes != null) { @@ -655,7 +652,12 @@ public boolean commitAndHandle() { } } - public void extractCauses(InvalidValueException[] causes) { + public InvalidValueException[] getAllCauses(InvalidValueException[] causes) { + List tempCauses = new ArrayList<>(); + return extractCauses(causes, tempCauses); + } + + public InvalidValueException[] extractCauses(InvalidValueException[] causes, List tempCauses) { for (InvalidValueException cause : causes) { if (cause.getCauses().length > 1) { extractCauses(cause.getCauses()); From 8422a0fe174c6cc297eb2643c5d29e8093ff0e49 Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Tue, 17 Jan 2023 10:58:40 +0100 Subject: [PATCH 130/166] remove heap size def --- sormas-e2e-tests/gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/gradle.properties b/sormas-e2e-tests/gradle.properties index 24426f1aae9..2bae239f790 100644 --- a/sormas-e2e-tests/gradle.properties +++ b/sormas-e2e-tests/gradle.properties @@ -20,7 +20,7 @@ org.gradle.daemon=true org.gradle.parallel=true #org.gradle.unsafe.configuration-cache=true #org.gradle.caching=true -org.gradle.jvmargs=-Xmx1024M +#org.gradle.jvmargs=-Xmx1024M allureVersion=2.10.0 allureJavaAdapterVersion=1.5.4 cucumberVersion=4.3.0 From 0b934e6b203ebecec9aa72295c731408c3251464 Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Tue, 17 Jan 2023 11:59:39 +0200 Subject: [PATCH 131/166] #9742 - Bad formatting of error message for missing information aroundVesiculopustular rash --- .../sormas/ui/utils/CommitDiscardWrapperComponent.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CommitDiscardWrapperComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CommitDiscardWrapperComponent.java index e0dad81f599..fc25d6c8e89 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CommitDiscardWrapperComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CommitDiscardWrapperComponent.java @@ -132,8 +132,6 @@ public static interface DeleteWithDetailsListener { private boolean shortcutsEnabled = false; protected transient List actions; - private List tempCauses; - protected CommitDiscardWrapperComponent() { } @@ -659,12 +657,13 @@ public InvalidValueException[] getAllCauses(InvalidValueException[] causes) { public InvalidValueException[] extractCauses(InvalidValueException[] causes, List tempCauses) { for (InvalidValueException cause : causes) { - if (cause.getCauses().length > 1) { - extractCauses(cause.getCauses()); + if (cause.getCauses().length > 0) { + extractCauses(cause.getCauses(), tempCauses); } else { tempCauses.add(cause); } } + return tempCauses.toArray(new InvalidValueException[] {}); } @Override From d7a13b0320f5675a5fa92167e9b0c99a22d49ac7 Mon Sep 17 00:00:00 2001 From: Halima Mohamed-Seghir Date: Tue, 17 Jan 2023 11:40:20 +0100 Subject: [PATCH 132/166] fixes in Countries counter xpath --- .../pages/application/configuration/CountriesTabPage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java index 11b49996a74..247647cb368 100644 --- a/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java +++ b/sormas-e2e-tests/src/main/java/org/sormas/e2etests/pages/application/configuration/CountriesTabPage.java @@ -37,7 +37,7 @@ public class CountriesTabPage { public static final By COUNTRY_GRID_RESULTS_ROWS = By.cssSelector("[role=rowgroup] tr a"); public static final By NUMBER_OF_COUNTRIES = By.xpath( - "//div[@class='v-slot v-slot-bold v-slot-vspace-top-none v-slot-align-right v-align-right v-align-middle']"); + "(//div[@class='v-slot v-slot-bold v-slot-vspace-top-none v-slot-align-right v-align-right v-align-middle'])[2]"); public static final By COUNTRIES_TABLE_DATA = By.tagName("td"); public static final By COUNTRIES_TABLE_ROW = By.cssSelector("div.v-grid-tablewrapper tbody tr"); public static final By COUNTRIES_NAME_TABLE_ROW = From 88316a7397b288a927e8d9ec5a3492b05a294001 Mon Sep 17 00:00:00 2001 From: Levente Gal <62599627+leventegal-she@users.noreply.github.com> Date: Tue, 17 Jan 2023 12:52:48 +0200 Subject: [PATCH 133/166] #10247 S2S Surveillance Reports should be shareable (along with possibly attached External Messages) [8] - fix saving external messages on accept (#11350) Co-authored-by: Levente Gal --- .../entities/ProcessedEntitiesPersister.java | 31 +++++++++++++++++++ .../sample/ProcessedSampleDataPersister.java | 16 ---------- ...cessedSurveillanceReportDataPersister.java | 11 ------- 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ProcessedEntitiesPersister.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ProcessedEntitiesPersister.java index e482878fb2f..98132572d7a 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ProcessedEntitiesPersister.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/ProcessedEntitiesPersister.java @@ -15,6 +15,10 @@ package de.symeda.sormas.backend.sormastosormas.entities; +import static de.symeda.sormas.backend.sormastosormas.ValidationHelper.buildValidationGroupName; +import static de.symeda.sormas.backend.sormastosormas.ValidationHelper.handleValidationError; + +import java.util.ArrayList; import java.util.List; import javax.ejb.EJB; @@ -23,6 +27,8 @@ import org.apache.commons.collections.CollectionUtils; +import de.symeda.sormas.api.externalmessage.ExternalMessageDto; +import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.sormastosormas.ShareTreeCriteria; import de.symeda.sormas.api.sormastosormas.SormasToSormasDto; import de.symeda.sormas.api.sormastosormas.SormasToSormasOriginInfoDto; @@ -31,6 +37,7 @@ import de.symeda.sormas.api.sormastosormas.entities.contact.SormasToSormasContactDto; import de.symeda.sormas.api.sormastosormas.entities.event.SormasToSormasEventDto; import de.symeda.sormas.api.sormastosormas.entities.event.SormasToSormasEventParticipantDto; +import de.symeda.sormas.api.sormastosormas.entities.externalmessage.SormasToSormasExternalMessageDto; import de.symeda.sormas.api.sormastosormas.entities.immunization.SormasToSormasImmunizationDto; import de.symeda.sormas.api.sormastosormas.entities.sample.SormasToSormasSampleDto; import de.symeda.sormas.api.sormastosormas.entities.surveillancereport.SormasToSormasSurveillanceReportDto; @@ -38,6 +45,7 @@ import de.symeda.sormas.backend.caze.CaseFacadeEjb; import de.symeda.sormas.backend.contact.ContactFacadeEjb; import de.symeda.sormas.backend.event.EventFacadeEjb; +import de.symeda.sormas.backend.externalmessage.ExternalMessageFacadeEjb.ExternalMessageFacadeEjbLocal; import de.symeda.sormas.backend.sormastosormas.entities.caze.ProcessedCaseDataPersister; import de.symeda.sormas.backend.sormastosormas.entities.contact.ProcessedContactDataPersister; import de.symeda.sormas.backend.sormastosormas.entities.event.ProcessedEventDataPersister; @@ -71,6 +79,8 @@ public class ProcessedEntitiesPersister { private ContactFacadeEjb.ContactFacadeEjbLocal contactFacade; @EJB private EventFacadeEjb.EventFacadeEjbLocal eventFacade; + @EJB + private ExternalMessageFacadeEjbLocal externalMessageFacade; public void persistSharedData(SormasToSormasDto processedData, SormasToSormasOriginInfoDto originInfo, ShareDataExistingEntities existingEntities) throws SormasToSormasValidationException { @@ -105,9 +115,13 @@ public void persistSharedData(SormasToSormasDto processedData, SormasToSormasOri } List samples = processedData.getSamples(); + List externalMessages = new ArrayList<>(); if (CollectionUtils.isNotEmpty(samples)) { for (SormasToSormasSampleDto s : samples) { sampleDataPersister.persistSharedData(s, originInfo, existingEntities.getSamples().get(s.getEntity().getUuid())); + if (!CollectionUtils.isEmpty(s.getExternalMessages())) { + externalMessages.addAll(s.getExternalMessages()); + } } } @@ -123,8 +137,25 @@ public void persistSharedData(SormasToSormasDto processedData, SormasToSormasOri for (SormasToSormasSurveillanceReportDto r : reports) { surveillanceReportDataPersister .persistSharedData(r, originInfo, existingEntities.getSurveillanceReports().get(r.getEntity().getUuid())); + + if (r.getExternalMessage() != null) { + externalMessages.add(r.getExternalMessage()); + } } } + + if (!externalMessages.isEmpty()) { + for (SormasToSormasExternalMessageDto s2sExternalMessage : externalMessages) { + ExternalMessageDto externalMessage = s2sExternalMessage.getEntity(); + + handleValidationError( + () -> externalMessageFacade.save(externalMessage, false, false), + Captions.ExternalMessage, + buildValidationGroupName(Captions.ExternalMessage, externalMessage), + externalMessage); + } + } + } public DuplicateResult checkForSimilarEntities(SormasToSormasDto processedData, ShareDataExistingEntities existingEntities) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/sample/ProcessedSampleDataPersister.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/sample/ProcessedSampleDataPersister.java index 28d148e0fb2..092715836bf 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/sample/ProcessedSampleDataPersister.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/sample/ProcessedSampleDataPersister.java @@ -24,15 +24,12 @@ import javax.ejb.LocalBean; import javax.ejb.Stateless; -import de.symeda.sormas.api.externalmessage.ExternalMessageDto; import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.sample.AdditionalTestDto; import de.symeda.sormas.api.sample.PathogenTestDto; import de.symeda.sormas.api.sample.SampleDto; -import de.symeda.sormas.api.sormastosormas.entities.externalmessage.SormasToSormasExternalMessageDto; import de.symeda.sormas.api.sormastosormas.entities.sample.SormasToSormasSampleDto; import de.symeda.sormas.api.sormastosormas.validation.SormasToSormasValidationException; -import de.symeda.sormas.backend.externalmessage.ExternalMessageFacadeEjb.ExternalMessageFacadeEjbLocal; import de.symeda.sormas.backend.sample.AdditionalTestFacadeEjb.AdditionalTestFacadeEjbLocal; import de.symeda.sormas.backend.sample.PathogenTestFacadeEjb.PathogenTestFacadeEjbLocal; import de.symeda.sormas.backend.sample.Sample; @@ -53,8 +50,6 @@ public class ProcessedSampleDataPersister extends ProcessedDataPersister externalMessageFacade.save(externalMessage, false, false), - Captions.ExternalMessage, - buildValidationGroupName(Captions.ExternalMessage, externalMessage), - externalMessage); - } - } @Override diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/surveillancereport/ProcessedSurveillanceReportDataPersister.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/surveillancereport/ProcessedSurveillanceReportDataPersister.java index 2855da1c74b..8fae11bb7d7 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/surveillancereport/ProcessedSurveillanceReportDataPersister.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sormastosormas/entities/surveillancereport/ProcessedSurveillanceReportDataPersister.java @@ -16,7 +16,6 @@ package de.symeda.sormas.backend.sormastosormas.entities.surveillancereport; import static de.symeda.sormas.backend.sormastosormas.ValidationHelper.buildSurveillanceReportValidationGroupName; -import static de.symeda.sormas.backend.sormastosormas.ValidationHelper.buildValidationGroupName; import static de.symeda.sormas.backend.sormastosormas.ValidationHelper.handleValidationError; import javax.ejb.EJB; @@ -24,7 +23,6 @@ import javax.ejb.Stateless; import de.symeda.sormas.api.caze.surveillancereport.SurveillanceReportDto; -import de.symeda.sormas.api.externalmessage.ExternalMessageDto; import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.sormastosormas.entities.surveillancereport.SormasToSormasSurveillanceReportDto; import de.symeda.sormas.api.sormastosormas.validation.SormasToSormasValidationException; @@ -73,15 +71,6 @@ protected void persistSharedData(SormasToSormasSurveillanceReportDto processedDa Captions.Immunization, buildSurveillanceReportValidationGroupName(report), report); - - if (processedData.getExternalMessage() != null) { - ExternalMessageDto externalMessage = processedData.getExternalMessage().getEntity(); - handleValidationError( - () -> externalMessageFacade.save(externalMessage, false, false), - Captions.ExternalMessage, - buildValidationGroupName(Captions.ExternalMessage, externalMessage), - externalMessage); - } } @Override From 40160a578c7a23192158d1e3d656c1687e32e6ff Mon Sep 17 00:00:00 2001 From: Pawel Kujawa Date: Tue, 17 Jan 2023 11:56:10 +0100 Subject: [PATCH 134/166] increased heap size + caching --- sormas-e2e-tests/gradle.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sormas-e2e-tests/gradle.properties b/sormas-e2e-tests/gradle.properties index 2bae239f790..cf7b0b82319 100644 --- a/sormas-e2e-tests/gradle.properties +++ b/sormas-e2e-tests/gradle.properties @@ -19,8 +19,9 @@ org.gradle.daemon=true org.gradle.parallel=true #org.gradle.unsafe.configuration-cache=true -#org.gradle.caching=true +org.gradle.caching=true #org.gradle.jvmargs=-Xmx1024M +org.gradle.jvmargs=-Xmx1024m allureVersion=2.10.0 allureJavaAdapterVersion=1.5.4 cucumberVersion=4.3.0 From a61f98592612a197a0bd7e4d8e5cc52ef96b7fad Mon Sep 17 00:00:00 2001 From: sergiupacurariu <62688603+sergiupacurariu@users.noreply.github.com> Date: Tue, 17 Jan 2023 14:32:25 +0200 Subject: [PATCH 135/166] #9742 - Bad formatting of error message for missing information aroundVesiculopustular rash --- .../utils/CommitDiscardWrapperComponent.java | 52 +++++++------------ 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CommitDiscardWrapperComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CommitDiscardWrapperComponent.java index fc25d6c8e89..23297132ede 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CommitDiscardWrapperComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/CommitDiscardWrapperComponent.java @@ -594,37 +594,24 @@ public boolean commitAndHandle() { } catch (InvalidValueException ex) { StringBuilder htmlMsg = new StringBuilder(); String message = ex.getMessage(); - if (message != null && !message.isEmpty()) { + if (message != null && !message.isEmpty() && ex.getCauses().length == 0) { htmlMsg.append(ex.getHtmlMessage()); } else { - InvalidValueException[] causes = getAllCauses(ex.getCauses()); + List causes = extractCauses(ex); if (causes != null) { - InvalidValueException firstCause = null; - boolean multipleCausesFound = false; - for (int i = 0; i < causes.length; i++) { - if (!causes[i].isInvisible()) { - if (firstCause == null) { - firstCause = causes[i]; - } else { - multipleCausesFound = true; - break; - } - } - } - if (multipleCausesFound) { + if (causes.size() > 1) { htmlMsg.append("
    "); // All again - for (int i = 0; i < causes.length; i++) { - if (!causes[i].isInvisible()) { - htmlMsg.append("
  • ").append(findHtmlMessage(causes[i])).append("
  • "); - } + for (InvalidValueException cause : causes) { + htmlMsg.append("
  • ").append(findHtmlMessage(cause)).append("
  • "); } htmlMsg.append("
"); - } else if (firstCause != null) { + } else if (causes.size() > 0) { htmlMsg.append("